1

我有一个 MySQL 查询,当前运行时间为 2.5 秒,我想将其缩短到最多 2 秒。

这是查询:

SELECT SQL_CALC_FOUND_ROWS Distinct(c.id) 
FROM   `content` c 
       INNER JOIN `actions` AS action 
               ON c.parent_id = action.primary_id 
WHERE  1 = 1 
       AND c.site_id IN ( 1, 2 ) 
       AND c.type IN ( 'topic' ) 
       AND c.status = 'visible' 
       AND ( c.lock = 0 
              OR c.site_id = 1 ) 
       AND ( c.level IN ( 0 ) 
              OR ( c.level IN ( 10 ) 
                   AND action.user_id = 123 
                   AND action.type IN ( 'group_follow' ) ) ) 
ORDER  BY c.date_updated DESC 
LIMIT  20 

以下是目前的统计数据:

  • 表格内容有 55k 行
  • 表操作有 87k 行

对于内容,我有以下索引:

  • parent_id (parent_id)
  • 用户 ID(用户 ID)
  • type_status_date(类型、状态、日期)
  • type_status_updateddate(类型,状态,date_updated)
  • 站点 ID(站点 ID)
  • type_status_level(类型、状态、级别)
  • type_parentid_level(类型,parent_id,级别)

对于操作,我有以下索引:

  • primary_id (primary_id)
  • 站点 ID(站点 ID)
  • 类型(类型)

任何帮助和建议将不胜感激。

谢谢大家!

4

2 回答 2

1

由于您正在执行“ORDER BY c.date_updated DESC LIMIT 20”,因此您可能需要在 c.date_updated 上创建索引。这样,mysql 可以先以相反的date_updated顺序扫描该表,并在它获得 20 行后立即停止。

您绝对应该EXPLAIN在更改之前和之后检查您的查询,以查看优化器是否选择了该顺序。date_updated如果优化器没有自然地选择索引,有一些方法可以强制使用索引。

于 2012-12-22T00:35:02.800 回答
0

在 where 子句中你必须有顺序。firsts 必须是具有索引的列。

例如对于索引 type_status_updateddate (type, status, date_updated)

如果我们写

where status = 'blabla' and type = '1'

索引不使用螺母

where type='1' and status='blala'

使用索引。

如果列保留在索引中(在多列索引中),mysql 使用索引。例如对于索引 type_status_updateddate (type, status, date_updated)

如果我们写 where status = 'blablabla' index not using

这个事实确实使用多列索引并不酷

c.type IN ( 'topic' )

可能会被替换

c.type = 'topic' 

对不起我的英语不好。

于 2012-12-23T16:32:15.603 回答