【发布时间】:2013-06-04 13:01:31
【问题描述】:
这是一个大约需要 1 毫秒才能完成的 mysql 查询:
SELECT SQL_NO_CACHE DISTINCT invoice.*,
GROUP_CONCAT(DISTINCT line.guid) as line
FROM invoice
LEFT JOIN ligne ON line.invoice = invoice.guid
GROUP BY invoice.guid
WHERE acompte = 1
LIMIT 0, 100;
如果我在查询中添加ORDER BY invoice.date,它会变得非常慢,大约需要 3 秒才能完成。
如果我删除 LEFT JOIN(和 GROUP_CONCAT),查询又需要 1 毫秒。
我添加了EXPLAIN 来查看查询速度慢时 MySQL 在做什么,我可以看到它正在使用临时文件:
1 SIMPLE invoice index NULL PRIMARY 4 NULL 25385 Using temporary; Using filesort
1 SIMPLE line ref invoice invoice 5 gestixi.invoice.guid 1 Using index
我确信有一种方法可以加快查询速度,但我找不到。有什么想法吗?
请注意,我无法在 date 上添加索引(顺便说一句,这不会改变任何内容),因为我希望我的用户能够对表格的每个字段进行排序。
另请注意,invoice.guid、line.invoice、line.guid 和 acompte 已编入索引。
编辑
如果我在没有 LEFT JOIN 但使用 ORDER BY 子句的情况下进行第一个查询以获取我想要的行的 id,然后在 WHERE 子句中使用这些 id 进行第二个查询(如上面的查询),我可以在不到 10 毫秒的时间内得到我需要的东西。
这让我相信它一定是一种在不添加索引的情况下加快查询速度的方法。
【问题讨论】:
-
尝试在
invoice.date字段上添加索引,因为它将在您使用 order by 子句时使用。用索引检查order by子句的解释,检查是否使用.. -
正如我所说,我不想在
invoice.date上添加索引,因为如果这样做,我将不得不为我的表的所有字段添加索引。无论如何,我尝试在其上添加一个索引并且它没有被使用(并且没有改变任何东西)。 -
好吧错过了你的意思...无论如何尝试在
invoice.date, invoice.guid上创建复合索引,如果未使用此索引,则尝试使用use index明确告诉查询优化器使用它
标签: mysql performance