2009-01-21 38 views
1

我有以下查询:我有哪些选择可以使我的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

+0

告诉我们您的MySQL版本以及您的索引是如何定义的... – 2009-01-21 21:17:00

+0

索引以及请... – Thorsten 2009-01-21 21:29:11

+0

索引在那里:KEY`client_name`(`client_name`) – 2009-01-21 21:32:25

回答

-1

是c.id标识列?如果是这样,我认为你不需要DISTINCT,因为每个c.id都是唯一的。

编辑

所以c.id可能在CP多个条目即使cp.project_id = 1?

编辑

只是珍玩,为什么要通过客户端名称,当你不选择它来订购。

0

c.id是否是主键?如果是这样,你不应该对它做DISTINCT,因为它已经不同了,强制DISTINCT可能会导致它按ID排序,然后按client_name排序。

-2

你为什么要按客户名称排序,如果你甚至没有返回它?

你也需要独特?

你为什么这样做左连接,如果你的where子句将使其内部反正

加入有了这个WHERE cp.project_id = 1,而不是和cp.project_id = 1 WHERE子句之前,它是一个INNEr JOIN无论如何

0

一些优化是数据库供应商中立,而其他优化是数据库供应商特定。这里有几件事要尝试。

  • 按照其他地方的建议删除DISTINCT。
  • 考虑使用内部连接。我意识到在你的情况下它可能不是一个可行的选择。

此外,运行一个执行计划,以获取有关查询的哪些部分占用最多时间和原因的更好图片。有关更多详细信息,请参阅EXPLAIN关键字。

2

看你的编辑

尝试使用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 
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)

2

尝试增加此键client_projects

KEY(client_name, id, active_flag) 
0

你需要强制指标的使用上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 
1

我没有解决方案给你,但我确实有一个解释。

MySQL只为每个表使用一个索引。您有两个表,并且这些表中使用的索引是其中一个的主键(WHERE cp.project_id = 1),并且连接强制使用第二个表索引来高效地连接。

在使用ORDER BY之后,因此MySQL不可能使用索引进行排序。添加更多索引不会有帮助。 EXPLAIN将向您显示MySQL为每个表选择了哪些索引。强制索引会导致查询的其他部分变慢。

相关问题