简体   繁体   English

大型数据库的MySQL查询优化

[英]Mysql query optimization for large database

We have large database, we have nearly two lake records, while we try to search using below query taking too long to bring the result 我们有大型数据库,我们有将近两个湖记录,而我们尝试使用下面的查询进行搜索却花费了太长时间才能得出结果

myquery 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, We have more derived queries in the loop so i need more optimization regarding @DRapp 编辑,我们在循环中有更多派生查询,所以我需要对@DRapp进行更多优化

answer 回答

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'
)

Thanks 谢谢

I've restructured your query. 我已经重组了您的查询。 Some of the where clauses were redundant (with respect to the e.owner_guid = 130), so superfluous elements removed. 一些where子句是多余的(相对于e.owner_guid = 130),因此删除了多余的元素。

I've added the MySQL clause "STRAIGHT_JOIN" to tell the engine to perform in the order provided by the tables and respective joins. 我添加了MySQL子句“ STRAIGHT_JOIN”,以告知引擎按照表和相应联接提供的顺序执行。 I started with your "m1" as the FIRST prequery to also include your criteria of "name_id" and "String" qualifiers. 我从您的“ m1”开始,这是第一个预查询,其中还包括“ name_id”和“ String”限定词的条件。 Ensure your elgg_metadata table has index on the name_id column. 确保您的elgg_metadata表在name_id列上具有索引。 Also, since you are not doing anything with any of the other columns from the metadata or meta strings table (except to qualify), I'm only returning the DISTINCT "entity_id". 另外,由于您对元数据或元字符串表中的任何其他列均不做任何事情(除限定条件外),因此我仅返回DISTINCT“ entity_id”。 This should return a quick small subset for you. 这应该为您返回一个快速的小子集。

From that result, only join those pre-qualified to your entities, users and relationships tables (left join on the relationships since that was an "OR" condition later). 从该结果中,仅将那些通过资格预审的实体加入到您的实体,用户和关系表中(在关系上保留左联接,因为以后是“ OR”条件)。 If it can't find a match on the entity ID, don't bother going any further. 如果在实体ID上找不到匹配项,请不要再费劲了。

THEN, the rest of the OR criteria can be applied... if the owner_guid = 130 OR found in eer (relationships) via left-join vs an IN (subselect) which would be a performance killer, and your final OR for the Access_ID. 然后,可以应用其余的OR条件...如果owner_guid = 130 OR通过左联接与IN(子选择)在eer(关系)中发现,OR将成为性能杀手,并且您对Access_ID的最终OR 。

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 )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM