2012-07-31 12 views
6

どのような方法や方法の組み合わせが最も速いのでしょうか?私は、MySQL上で明確なを聞いたパフォーマンスとソート、および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); 

は、大規模なクエリの本当の大きなパフォーマンスヒットであり、この表には、万行以上を持つことができます。私は、InnodbやMyISAMのどのような組み合わせのデータベースが最適に機能するのか疑問に思いました。私は、多くの最適化が非常にクエリに依存することを知っています。年は符号なしの数値ですが、他のフィールドは異なる長さの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を使用すると効率的です。そうしないと、個別の行をフェッチするために全表スキャンが必要になります。 MySQLではなく、PHPで個別の行をソートしようとすると、MySQLからPHPにさらに多くのデータが(潜在的に)送信され、PHPはそのデータをすべて保存してから重複をなくします。

私が持っているdevデータベースの出力例です。また、このデータベースは、クエリが実行されているネットワーク上の別のサーバーにあることにも注意してください。

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 | 
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+ 

私は非インデックスであるものとSerialNumber列を置き換える以外は同じクエリを、しようとした場合、MySQLはすべて97百万行を検討する必要があるため、それを実行するために永遠にかかります。

効率性のいくつかは、どれだけのデータを取得することが予想されているかに関係しています。 time列(読み取りのタイムスタンプ)で動作する上記のクエリをわずかに変更すると、273,505回の別個のリストを取得するのに1分40秒かかります。オーバーヘッドのほとんどは、すべてのレコードをネットワーク。したがって、戻っていくデータの量の制限を念頭に置いて、フェッチしようとしているデータの可能な限り低く保つ必要があります。最終的なクエリについては

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、year、line)' –

+0

です。 – Wolfe

関連する問題