【问题标题】:MySQL 8 slow with descending composite indexMySQL 8 速度慢,复合索引下降
【发布时间】:2019-04-21 02:03:57
【问题描述】:

我有以下疑问:

SELECT 
      shows.id, 
      shows.title, 
      shows.thumbnail, 
      shows.views, 
      shows.likes, 
      shows.dislikes, 
      shows.duration, 
      shows.hd, 
      shows.origin, 
      UNIX_TIMESTAMP(shows.upload_date) as upload_date 
   FROM 
      shows 
   WHERE 
          (shows.views, shows.id) < (0, 272990) 
      and shows.visible = 1 
   ORDER BY 
      shows.views DESC, 
      shows.id DESC 
   LIMIT 
      32

在 MySQL 8.0.15 中大约需要 0.8 秒。

我尝试过这样的索引:

CREATE INDEX views_desc_id_desc_visible ON shows (views desc, id desc, visible)

还有这样的:

CREATE INDEX views_desc_id_desc ON shows (views desc, id desc)

还有许多其他排列。我已经删除了它们并从头开始重做了很多次。 Visible 本身确实有一个索引。

当我进行解释时,我看到它仅在使用名为 views_desc_id_desc_visible 的键时执行“使用 where”。从查询中删除可见并不会改变它的性能。删除两个 desc(因此:按视图排序,id)确实使它成为 0.0008 秒。

为什么不快点?

更新(复制自评论)

SELECT  shows.id, shows.title, shows.thumbnail, shows.views, shows.likes,
        shows.dislikes, shows.duration, shows.hd, shows.origin,
        UNIX_TIMESTAMP(shows.upload_date) as upload_date
    FROM  shows
    WHERE      (shows.views <= 0)
      and  not (shows.views  = 0 and shows.id >= 272990)
      and  visible = 1
    ORDER BY  shows.views DESC, shows.id DESC
    LIMIT  32

修复它。我只是不知道为什么使用其他方式会忽略索引。

【问题讨论】:

  • 好像和这个有关:(shows.views,shows.id)
  • 选择shows.id、shows.title、shows.thumbnail、shows.views、shows.likes、shows.dislikes、shows.duration、shows.hd、shows.origin、UNIX_TIMESTAMP(shows.upload_date ) 因为 upload_date FROM 显示 WHERE (shows.views = 272990) 和 visible = 1 ORDER BY shows.views DESC,shows.id DESC LIMIT 32 修复它。我只是不知道为什么使用其他方式会忽略索引。
  • views 可以否定吗?

标签: mysql indexing composite-index


【解决方案1】:

visible 必须在索引中排在第一位

INDEX(visible, views DESC, id DESC)

构建最优索引的一般规则是:

  1. 包括WHERE 中使用= constant 测试的所有列。
  2. 然后是其他列。

更多详情:http://mysql.rjweb.org/doc.php/index_cookbook_mysql

WHERE (shows.views, shows.id) &lt; (0, 272990) 一起使用的“行构造函数”存在可能问题。这在 5.7 之前根本没有优化。

解决方法(5.7 之前)是优化了您在评论中提到的复杂表达式。它可能仍在优化:

WHERE      (shows.views <= 0)
  and  not (shows.views  = 0 and shows.id >= 272990)

8.0 在索引声明中引入了尊重DESC

我担心优化器未能将这两个增强功能组合在一起来满足您的需求。

请告诉我们EXPLAIN SELECT... 以供您尝试。尤其看Key_len

即使没有 8.0,我也会推荐

INDEX(visible, views, id)

在这种情况下,可以将索引向后遍历来处理

WHERE visible = 0
  AND ...
ORDER BY views DESC, id DESC

这是假设行构造函数问题已解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    相关资源
    最近更新 更多