我有哪些选择可以使我的ORDER BY更快?
我有以下查询:我有哪些选择可以使我的ORDER BY更快?
SELECT DISTINCT c.id
FROM clients AS c
LEFT JOIN client_project AS cp ON (cp.client_id = c.id)
WHERE cp.project_id = 1
AND c.active_flag = 1
ORDER BY c.client_name
如果我通过删除订单,查询需要0.005秒。按顺序,查询需要1.8-1.9秒。我有一个索引client_name
。
还有什么可以提高速度?
编辑: c.id是主键,但在client_project中可能有多个记录,因此它可能会为每个id导致多条记录。此外,删除不同的查询会产生0.1秒的差异。
增加:这里是我的客户表:
CREATE TABLE IF NOT EXISTS `clients` (
`id` int(11) NOT NULL auto_increment,
...
`organization` varchar(255) character set utf8 collate utf8_bin NOT NULL,
`client_name` varchar(255) character set utf8 collate utf8_bin NOT NULL,
`active_flag` tinyint(1) NOT NULL,
...
PRIMARY KEY (`id`),
KEY `active_flag` (`active_flag`),
...
KEY `organization` (`organization`),
KEY `client_name` (`client_name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
使用MySQL 5.0
是c.id标识列?如果是这样,我认为你不需要DISTINCT,因为每个c.id都是唯一的。
编辑
所以c.id可能在CP多个条目即使cp.project_id = 1?
编辑
只是珍玩,为什么要通过客户端名称,当你不选择它来订购。
c.id是否是主键?如果是这样,你不应该对它做DISTINCT,因为它已经不同了,强制DISTINCT可能会导致它按ID排序,然后按client_name排序。
你为什么要按客户名称排序,如果你甚至没有返回它?
你也需要独特?
你为什么这样做左连接,如果你的where子句将使其内部反正
加入有了这个WHERE cp.project_id = 1,而不是和cp.project_id = 1 WHERE子句之前,它是一个INNEr JOIN无论如何
一些优化是数据库供应商中立,而其他优化是数据库供应商特定。这里有几件事要尝试。
- 按照其他地方的建议删除DISTINCT。
- 考虑使用内部连接。我意识到在你的情况下它可能不是一个可行的选择。
此外,运行一个执行计划,以获取有关查询的哪些部分占用最多时间和原因的更好图片。有关更多详细信息,请参阅EXPLAIN关键字。
看你的编辑
尝试使用EXISTS在这种情况下
SELECT c.id
FROM clients AS c
WHERE EXISTS (SELECT * FROM client_project AS cp
WHERE cp.client_id = c.id and cp.project_id = 1)
AND c.active_flag = 1
大概有上clients.id和clients.active_flag指数,所以没有必要优化去全表(或额外的索引),除非你想排序。
检查优化器计划,我想在mySQL中解释。
client_name,id上的索引可能会有所帮助(或者它可能无法检查计划)。
一对夫妇产生额外的问题/思想/言论可能有助于...的
- 为什么,如果你有秩序的名字,如果你从选择得到的是ID
- 为什么左连接“cp.project_id”中的where子句,因此没有项目的客户将不会被退回
-
对于其他海报(paul,eppz),对于拥有多个项目的客户可能需要“独特”。因此,另一种想法是从客户ç 这样做
选择ID 其中存在 (SELECT * FROM client_project CP其中c.id = cp.client_id)
尝试增加此键client_projects
:
KEY(client_name, id, active_flag)
你需要强制指标的使用上client_name
:
SELECT id
FROM (
SELECT c.id,
(
SELECT 1
FROM client_projects cp
WHERE cp.client_id = c.id
AND cp.project_id = 1
LIMIT 1
) e
FROM clients c
FORCE INDEX (client_name)
WHERE c.active_flag = 1
ORDER BY
client_name
) co
WHERE e IS NOT NULL
我没有解决方案给你,但我确实有一个解释。
MySQL只为每个表使用一个索引。您有两个表,并且这些表中使用的索引是其中一个的主键(WHERE cp.project_id = 1),并且连接强制使用第二个表索引来高效地连接。
在使用ORDER BY之后,因此MySQL不可能使用索引进行排序。添加更多索引不会有帮助。 EXPLAIN将向您显示MySQL为每个表选择了哪些索引。强制索引会导致查询的其他部分变慢。
告诉我们您的MySQL版本以及您的索引是如何定义的... – 2009-01-21 21:17:00
索引以及请... – Thorsten 2009-01-21 21:29:11
索引在那里:KEY`client_name`(`client_name`) – 2009-01-21 21:32:25