2009-01-21 70 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爲每個表選擇了哪些索引。強制索引會導致查詢的其他部分變慢。

相關問題