讓MySQL做盡可能多的工作。如果它在做什麼時效率不高,那麼事情可能沒有正確設置(無論是正在嘗試運行的查詢的索引還是使用排序緩衝區的設置)。
如果您有year
列的索引,那麼使用DISTINCT
應該是有效的。如果你不這樣做,那麼爲了獲取不同的行,必須進行全表掃描。如果您嘗試在PHP中而不是MySQL中對不同的行進行分類,那麼您可能將更多的數據從MySQL傳輸到PHP,並且在消除重複之前,PHP會消耗更多的內存來存儲所有數據。
這是我從一個開發數據庫的一些示例輸出。另請注意,此數據庫位於執行查詢的網絡上的其他服務器上。
SELECT COUNT(SerialNumber) FROM `readings`;
> 97698592
SELECT SQL_NO_CACHE DISTINCT `SerialNumber`
FROM `readings`
ORDER BY `SerialNumber` DESC
LIMIT 10000;
> Fetched 10000 records. Duration: 0.801 sec, fetched in: 0.082 sec
> EXPLAIN *above_query*
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+
| 1 | SIMPLE | readings | range | NULL | PRIMARY | 18 | NULL | 19 | Using index for group-by; Using temporary; Using filesort |
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+
如果我試圖相同的查詢,除了一個是未編入索引,那麼它永遠運行,因爲MySQL有檢查全部97萬行更換SerialNumber
列。
一些效率與您期望得到的數據量有關。如果我稍微修改上述查詢以在time
列(讀數的時間戳)上進行操作,則需要花費1分40秒來獲得273,505次的明確列表,其中大部分開銷是將所有記錄通過網絡。因此,請記住您獲取多少數據的限制,您希望儘可能降低您嘗試獲取的數據的數據量。
至於你的最終查詢:
select distinct line from car_cache
where year='$postyear' and make='$postmake'
order by line desc
應該有與不成問題,只要確保你在year
和make
,並可能對line
指數具有複合指數。
關於最後一點,我使用的讀數表的引擎是InnoDB的,我的服務器是:5.5.23-55-log Percona Server (GPL), Release 25.3
這是Percona的公司
希望幫助一個版本的MySQL。
對於最終的查詢,最好的索引可以是'(年,make,line)'或'(make,year,line)' – 2012-07-31 18:43:17
偉大的徹底的答案不能要求更好的謝謝:) – Wolfe 2012-07-31 20:33:42