我正在寻找可能的最佳查询来获取给定记录集的最新日期,其中我需要过滤的字段是:
更简单的查询就是这个
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。
好的,我没有使用索引,我正在使用text和datetime列...我想这不是一个简单的场景所以我决定在表中添加一个与DocumentSeries具有相同含义的列但是是一个int,所以查询将是:
SELECT MAX(CreateDate) FROM transactionsheaders WHERE TransactionStatus="N" AND DocumentSeriesUID=2;
并添加了一个索引,用
来聚合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);
但......如果我使用ORDER BY,我不需要MAX而我只限制为1?
SELECT CreateDate FROM transactionsheaders WHERE TransactionStatus="N" AND DocumentSeriesUID='2' ORDER BY CreateDate DESC LIMIT 1;
和EXPLAIN产生与使用MAX的查询相同的结果。
嗯,所有这些只是问我如何优化这个查询?它是否已经通过唱指数进行了优化?我可以走得更远吗?
干杯
答案 0 :(得分:2)
查询
SELECT MAX(CreateDate)
FROM transactionsheaders
WHERE TransactionStatus="N" AND DocumentSeriesUID=2;
索引应为(TransactionStatus, DocumentSeriesUID, CreateDate)
或(DocumentSeriesUID, TransactionStatus, CreateDate)
,具体取决于基数。首先使用字段上的条件,然后在找到的行中查找最大的CreateDate。
答案 1 :(得分:0)
定义多字段索引时,必须确保按照指定的顺序使用字段。
e.g。给定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
,或者为字段创建仅a,c
的辅助索引。