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
ちょうどあなたがyear
とmake
上の複合インデックスと、おそらくline
にインデックスを持っていることを確認し、いずれかのように問題があってはなりません。最後のノートで
、私は読書テーブルのために使用していますエンジンはInnoDBテーブルで、私のサーバーは、次のとおりです。5.5.23-55-log Percona Server (GPL), Release 25.3
役立ちますPercona社のMySQLのバージョン
希望しています。
最終的には、最高のインデックスは '(年、行、行)'または '(make、year、line)' –
です。 – Wolfe