2012-07-31 66 views
6

在像這樣的情況下,哪種方法或哪種方法混合執行最快?在mysql和php之間的性能和排序以及獨特的獨特性

$year = db_get_fields("select distinct year from car_cache order by year desc"); 

或者

$year = db_get_fields("select year from car_cache"); 
$year = array_unique($year); 
sort($year); 

我聽說過關於MySQL的不同是大型查詢一個真正的大的性能損失,這表只能有一百萬行以上。我想知道什麼樣的數據庫類型Innodb或MyISAM的組合最適合。我知道很多優化都是非常依賴查詢的。 Year是一個無符號數字,但其他字段是不同長度的varchar我知道這也可能有所不同。如:

$line = db_get_fields("select distinct line from car_cache where year='$postyear' and make='$postmake' order by line desc"); 

我讀到,使用新的innodb多鍵方法可以使這樣的查詢非常非常快。但條款的獨特和順序是我的紅旗。

回答

4

讓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 

應該有與不成問題,只要確保你在yearmake,並可能對line指數具有複合指數。

關於最後一點,我使用的讀數表的引擎是InnoDB的,我的服務器是:5.5.23-55-log Percona Server (GPL), Release 25.3這是Percona的公司

希望幫助一個版本的MySQL。

+1

對於最終的查詢,最好的索引可以是'(年,make,line)'或'(make,year,line)' – 2012-07-31 18:43:17

+0

偉大的徹底的答案不能要求更好的謝謝:) – Wolfe 2012-07-31 20:33:42