【发布时间】:2011-03-21 08:17:20
【问题描述】:
我有这个问题
SELECT l.licitatii_id,
l.nume,
l.data_publicarii,
l.data_limita
FROM licitatii_ue l
INNER JOIN domenii_licitatii dl
ON l.licitatii_id = dl.licitatii_id
AND dl.tip_licitatie = '2'
INNER JOIN domenii d
ON dl.domenii_id = d.domenii_id
AND d.status = 1
AND d.tip_domeniu = '1'
WHERE l.status = 1
AND Unix_timestamp(TIMESTAMPADD(DAY, 1, CAST(From_unixtime(l.data_limita)
AS DATE)))
< '1300683793'
GROUP BY l.licitatii_id
ORDER BY data_publicarii DESC
解释输出:
+-----+--------------+--------+---------+-------------------------------------+----------+----------+---------------------------+-------+-----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
| 1 | SIMPLE | d | ALL | PRIMARY,key_status_tip_domeniu | NULL | NULL | NULL | 120 | 85.83 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | dl | ref | PRIMARY,tip_licitatie,licitatii_id | PRIMARY | 4 | web61db1.d.domenii_id | 6180 | 100.00 | Using where; Using index |
| 1 | SIMPLE | l | eq_ref | PRIMARY | PRIMARY | 4 | web61db1.dl.licitatii_id | 1 | 100.00 | Using where |
+-----+--------------+--------+---------+-------------------------------------+----------+----------+---------------------------+-------+-----------+----------------------------------------------+
如你所见 type=ALL for d table
现在如果我在查询中添加LIMIT 100
计划更改为range:
+-----+--------------+--------+---------+-------------------------------------+-------------------------+----------+---------------------------+-------+-----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
| 1 | SIMPLE | d | range | PRIMARY,key_status_tip_domeniu | key_status_tip_domeniu | 9 | NULL | 103 | 100.00 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | dl | ref | PRIMARY,tip_licitatie,licitatii_id | PRIMARY | 4 | web61db1.d.domenii_id | 6180 | 100.00 | Using where; Using index |
| 1 | SIMPLE | l | eq_ref | PRIMARY | PRIMARY | 4 | web61db1.dl.licitatii_id | 1 | 100.00 | Using where |
+-----+--------------+--------+---------+-------------------------------------+-------------------------+----------+---------------------------+-------+-----------+----------------------------------------------+
为什么会这样?
这个查询能不能再优化一下,两个查询都需要13秒。
表架构在 gist github 上可见
【问题讨论】:
-
假设前者更快,您能否不强制索引为 PRIMARY?
-
Schema 急需聚集主键索引——应该使用 innodb !有很多关于优化增强的建议,但它们过于广泛,即重写。
-
@f00 如果你能帮助我,我愿意采取行动。我们需要为 FULLTEXT 索引找到一些替代方案。
-
如果您必须使用全文而不是第 3 方,您可以执行我在此处建议的操作 stackoverflow.com/questions/4732067/… 这为您提供了 innodb 的全部优势,例如集群 PK 索引、事务、行级锁定等...但补充了 myisam 的 FT 功能
-
在尝试之前先阅读这篇文章,看看你是否明白这一点 stackoverflow.com/questions/4419499/… 你永远不知道,它可能会激励你自己朝着正确的方向前进 :)
标签: mysql sql query-optimization