谁能协助我优化查询以减少结果时间?

时间:2019-01-18 11:42:31

标签: mysql query-performance

我编写的MYSQL查询在这方面没有太多专业知识,但是随着数据库规模的增加,我发现返回结果花费的时间太长。我可以理解为什么,但是我不知道如何更好地对查询进行分组,以使MYSQL不会搜索整个数据库以返回结果。我知道有一种更有效的方法可以做到这一点,但我不知道怎么做。如果删除ORDER BY语句,则将在不到四分之一的时间内返回结果。现在,它的表中有180,000个条目(成员),返回结果大约需要4秒钟。

SELECT members.mem_id, members.username, members.online, 
       members.dob, members.regdate, members.sex, 
       members.mem_type, members.aboutme, 
       geo_cities.name AS city, 
       geo_countries.name AS country, photos.photo_path
        FROM members
        LEFT JOIN geo_cities
        ON members.cty_id=geo_cities.cty_id
        LEFT OUTER JOIN geo_countries
        ON geo_cities.con_id=geo_countries.con_id
        RIGHT OUTER JOIN photos
        ON members.mem_id=photos.mem_id
        WHERE (photos.main=1 
          AND photos.approved=1
          AND members.banned!="1"
          AND members.profile_photo="1"
          AND members.profile_essentials="1"
          AND members.profile_user="1")
        ORDER BY lastdate DESC
        LIMIT 12

1 个答案:

答案 0 :(得分:1)

您似乎想显示符合特定条件的最近12位成员。

几件事。

  1. 您在RIGHT JOIN上的photos实际上是一个普通的内部JOIN:其列显示在您的WHERE子句中。
  2. 您可能需要在membersphotos表上使用复合索引。
  3. SELECT many columns FROM ... JOIN ... ORDER BY column... LIMIT 12是一个臭名昭著的性能反模式:它构造了一个复杂的结果集,然后对整个结果进行排序,然后丢弃几乎所有结果。浪费。
  4. 您拥有WHERE....members.banned != "1"这样的不等式过滤器,这使SQL的工作比同等的工作更困难(==更慢)。如果您可以将其更改为= "0"或类似的方法。

(我想您的lastdate列在您的members表中,但是您没有在问题中告诉我们。)

因此,尝试执行类似的操作以找到要显示的十二个成员。

          SELECT members.mem_id
            FROM members
            JOIN photos ON members.mem_id=photos.mem_id
           WHERE photos.main=1 
             AND photos.approved=1
             AND members.banned!="1"
             AND members.profile_photo="1"
             AND members.profile_essentials="1"
             AND members.profile_user="1")
           ORDER BY lastdate DESC
           LIMIT 12

这样可以获取所需的十二个成员的ID。在主查询中使用它。

    SELECT members.mem_id, members.username, members.online, 
           members.dob, members.regdate, members.sex, 
           members.mem_type, members.aboutme, 
           geo_cities.name AS city, 
           geo_countries.name AS country, photos.photo_path
      FROM members
      LEFT JOIN geo_cities    ON members.cty_id=geo_cities.cty_id
      LEFT JOIN geo_countries ON geo_cities.con_id=geo_countries.con_id
      JOIN photos ON members.mem_id=photos.mem_id
    WHERE members.mem_id IN (
          SELECT members.mem_id
            FROM members
            JOIN photos ON members.mem_id=photos.mem_id
           WHERE photos.main=1 
             AND photos.approved=1
             AND members.banned!="1"
             AND members.profile_photo="1"
             AND members.profile_essentials="1"
             AND members.profile_user="1")
           ORDER BY lastdate DESC
           LIMIT 12
         )
    ORDER BY lastdate DESC
    LIMIT 12

这将找到您关心的十二个成员,然后仅提取其记录,而不是提取所有记录。

然后,在members(profile_photo, profile_essentials, profile_user, banned, lastdate)上创建一个复合索引。该复合索引将大大加快您的WHERE子句的速度。

同样,在photos(mem_id, main, approved, photo_path)上创建复合索引。

当数据库开始增长时,事情总是令人兴奋!阅读Markus Winand的在线书籍https://use-the-index-luke.com/