2012-01-17 22 views
1

我找得到一個給定的記錄集的最新日期,其中字段我需要過濾儘可能最佳的查詢優化SQL查詢是:與agregate指數

  • CREATEDATE:DATETIME
  • 的TransactionStatus :VARCHAR(10)
  • DocumentSeries:VARCHAR(45)

比較簡單的查詢是這個

SELECT MAX(CreateDate) FROM transactionsheaders WHERE TransactionStatus="N" AND DocumentSeries='Z'; 

當我使用我解釋得

EXPLAIN(SELECT MAX(CreateDate) FROM transactionsheaders WHERE TransactionStatus="N" AND DocumentSeries='Z'); 
+----+-------------+---------------------+------+---------------+------+---------+------+------+-------------+ 
| id | select_type | table    | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+---------------------+------+---------------+------+---------+------+------+-------------+ 
| 1 | SIMPLE  | transactionsheaders | ALL | NULL   | NULL | NULL | NULL | 5752 | Using where | 
+----+-------------+---------------------+------+---------------+------+---------+------+------+-------------+ 

,共記錄集的5715

好吧,我有沒有索引的使用,我用文字和datetime列...我想這不是一件容易的情況下,所以我決定將列添加到具有意義DocumentSeries相同,但一個int表,所以查詢將是:

SELECT MAX(CreateDate) FROM transactionsheaders WHERE TransactionStatus="N" AND DocumentSeriesUID=2; 

並且增加了agregates的索引3柱納秒與

ALTER TABLE `transactionsheaders` ADD INDEX `index_doc_series` (`DocumentSeriesUID` ASC, `CreateDate` ASC, `TransactionStatus` ASC); 

和解釋輸出

+----+-------------+---------------------+------+------------------+------------------+---------+-------+------+--------------------------+ 
| id | select_type | table    | type | possible_keys | key    | key_len | ref | rows | Extra     | 
+----+-------------+---------------------+------+------------------+------------------+---------+-------+------+--------------------------+ 
| 1 | SIMPLE  | transactionsheaders | ref | index_doc_series | index_doc_series | 4  | const | 2876 | Using where; Using index | 
+----+-------------+---------------------+------+------------------+------------------+---------+-------+------+--------------------------+ 

Q1。呃...顯然我使用的數據較少,但是如果我使用相同的條件進行計數,則會得到5703個結果,因此,這有點令人困惑。我知道EXPLAIN估計查詢需要獲取的行數,但它怎麼可能關閉?

再說,我不如果我需要一次全部搞定一切,所以我的下一個考驗將是取前10個結果是適合我的搜索條件

SELECT MAX(Q.CreateDate) FROM((SELECT CreateDate FROM transactionsheaders WHERE TransactionStatus="N" AND DocumentSeriesUID='2' ORDER BY CreateDate DESC LIMIT 10) as Q); 

,但... m使用ORDER BY,我不需要MAX,我只限於1?

SELECT CreateDate FROM transactionsheaders WHERE TransactionStatus="N" AND DocumentSeriesUID='2' ORDER BY CreateDate DESC LIMIT 1; 

和EXPLAIN產生與使用MAX查詢相同的結果。

那麼,所有這些只是問我該如何優化這個查詢?它是否已經通過唱出索引進行了優化?我可以走得更遠嗎?

乾杯

回答

2

對於查詢

SELECT MAX(CreateDate) 
FROM transactionsheaders 
WHERE TransactionStatus="N" AND DocumentSeriesUID=2; 

的指數應(TransactionStatus, DocumentSeriesUID, CreateDate)(DocumentSeriesUID, TransactionStatus, CreateDate)取決於基數。您首先在字段上使用條件,然後在找到的行中查找最大CreateDate。

0

當你定義一個多字段索引,你必須確保你在他們指定的順序使用的字段。

例如給予index(a,b,c),然後

... where a=? 
... where a=? and b=?  
... where b=? and a=? 
... where a=? and b=? and c=? 

都可以使用索引,因爲你已經使用了索引的字段,他們定義的順序。在你的情況,你已經完成

... where a=? and c=? 

和省略b,它阻止使用該索引。將多字段索引中的字段視爲「鏈接」。爲了能夠到達索引中的'c'字段,您必須通過'b',但是您沒有在where子句中指定任何'b'字段。

請注意,如果您有索引字段的a,b,c,那麼您的where子句只需要使用它們中的所有字段,那麼字段在where子句中出現的實際順序就無關緊要了 - 這就是存在/不存在重要的字段。

要麼重新安排您的索引定義,以便它變爲a,c,b,要麼爲字段創建僅具有​​的二級索引。