2012-04-12 3 views
0

Мы имеем большую базу данных, мы имеем почти два озеро записи, в то время как мы пытаемся найти, используя ниже запрос занимает слишком много времени, чтобы принести результатMysql оптимизация запросов для большой базы данных

myquery

SELECT 
     count(DISTINCT e.guid) AS total 
    FROM 
     elgg_entities e 
     JOIN elgg_users_entity u 
      ON e.guid = u.guid 
     JOIN (SELECT 
         subm1.*, 
         s1.string 
        FROM 
         elgg_metadata subm1 
         JOIN elgg_metastrings s1 
          ON subm1.value_id = s1.id) AS m1 
      ON e.guid = m1.entity_guid 
    WHERE 
      m1.name_id = '332' 
     AND m1.string LIKE '%96059%' 
     AND (( e.access_id = -2 
       AND e.owner_guid IN (SELECT guid_one 
             FROM elgg_entity_relationships 
             WHERE relationship = 'friend' 
              AND guid_two =130) 
      ) 
      OR 
      ( e.access_id IN (2, 1, 3, 4, 6, 7) 
       OR (e.owner_guid = 130) 
       OR ( e.access_id = 0 
        AND e.owner_guid = 130) 
      ) 
      AND e.enabled = 'yes' 
     ) 

my query explain

Edit, мы более полученных запросов в цикле, поэтому мне нужно больше оптимизации относительно @DRapp

ответ

SELECT count(DISTINCT e.guid) AS total 
FROM elgg_entities e 
JOIN elgg_users_entity u ON e.guid = u.guid 
JOIN (

SELECT subm1 . * , s1.string 
FROM elgg_metadata subm1 
JOIN elgg_metastrings s1 ON subm1.value_id = s1.id 
) AS m1 ON e.guid = m1.entity_guid 
JOIN (

SELECT subm2 . * , s2.string 
FROM elgg_metadata subm2 
JOIN elgg_metastrings s2 ON subm2.value_id = s2.id 
) AS m2 ON e.guid = m2.entity_guid 
WHERE (
(
subm1.name_id = '332' 
AND s1.string LIKE '%10001%' 
) 
AND (
subm2.name_id = '328' 
AND s2.string LIKE '%New York%' 
) 
) 
AND (
(
e.access_id = -2 
AND e.owner_guid 
IN (

SELECT guid_one 
FROM elgg_entity_relationships 
WHERE relationship = 'friend' 
AND guid_two =2336 
) 
) 
OR (
e.access_id 
IN (2, 1) 
OR (
e.owner_guid =2336 
) 
OR (
e.access_id =0 
AND e.owner_guid =2336 
) 
) 
AND e.enabled = 'yes' 
) 
AND (
(
subm1.access_id = -2 
AND subm1.owner_guid 
IN (

SELECT guid_one 
FROM elgg_entity_relationships 
WHERE relationship = 'friend' 
AND guid_two =2336 
) 
) 
OR (
subm1.access_id 
IN (2, 1) 
OR (
subm1.owner_guid =2336 
) 
OR (
subm1.access_id =0 
AND subm1.owner_guid =2336 
) 
) 
AND subm1.enabled = 'yes' 
) 
AND (
(
subm2.access_id = -2 
AND subm2.owner_guid 
IN (

SELECT guid_one 
FROM elgg_entity_relationships 
WHERE relationship = 'friend' 
AND guid_two =2336 
) 
) 
OR (
subm2.access_id 
IN (2, 1) 
OR (
subm2.owner_guid =2336 
) 
OR (
subm2.access_id =0 
AND subm2.owner_guid =2336 
) 
) 
AND subm2.enabled = 'yes' 
) 

Благодаря

+0

Как можно лучше, не могли бы вы описать, что это такое, вы ПЫТАЕСЬ, и что такое «почти две записи озера»? – DRapp

ответ

1

Я перестроенный ваш запрос. Некоторые из предложений where были излишними (относительно e.owner_guid = 130), поэтому лишние элементы удалены.

Я добавил предложение MySQL «STRAIGHT_JOIN», чтобы сообщить движку выполнить в порядке, предусмотренном таблицами и соответствующими объединениями. Я начал с вашего «m1» в качестве ПЕРВОГО превью, чтобы также включить ваши критерии «name_id» и «String». Убедитесь, что таблица elgg_metadata имеет индекс в столбце name_id. Кроме того, поскольку вы ничего не делаете с какими-либо из других столбцов из таблицы метаданных или мета-строк (за исключением квалификации), я возвращаю DISTINCT «entity_id». Это должно вернуть вам небольшое небольшое подмножество.

Из этого результата присоединяйтесь только к тем, которые были предварительно определены для ваших сущностей, таблиц пользователей и отношений (левое соединение в отношениях, поскольку это было условие «ИЛИ» позже). Если он не может найти совпадение с идентификатором объекта, не беспокойтесь идти дальше.

THEN, остальные критерии OR могут быть применены ... если owner_guid = 130 ИЛИ найденный в eer (отношениях) через левое соединение против IN (подзаголовок), который будет убийцей производительности, и ваш окончательный ИЛИ для Access_ID.

SELECT STRAIGHT_JOIN 
     count(DISTINCT e.guid) AS total 
    FROM 
     (SELECT DISTINCT 
       subm1.entity_id 
      FROM 
       elgg_metadata subm1 
       JOIN elgg_metastrings s1 
        ON subm1.value_id = s1.id 
      WHERE 
        subm1.name_id = '332' 
       AND s1.string LIKE '%96059%') AS m1 

     JOIN elgg_entities e 
      ON m1.entity_id = e.guid 
      AND e.enabled = 'yes' 

      JOIN elgg_users_entity u 
       ON e.guid = u.guid 

      LEFT JOIN elgg_entity_relationships eer 
       ON e.owner_guid = eer.guid_one 
       AND eer.relationship = 'friend' 
       AND eer.guid_two = 130 
       AND e.access_id = -2 
    WHERE 
     e.owner_guid = 130 
     OR eer.guid_one = e.owner_guid 
     OR e.access_id IN (2, 1, 3, 4, 6, 7) 
+0

@selva, huh ???? – DRapp

+0

Вы можете проверить эту ссылку http://stackoverflow.com/a/10196376/1329306 – selva

+0

Пожалуйста, проверьте мои запросы на редактирование – selva

Смежные вопросы