Lassen Sie MySQL so viel wie möglich arbeiten. Wenn es bei dem, was es tut, nicht effizient ist, dann sind die Dinge wahrscheinlich nicht richtig eingerichtet (ob es eine korrekte Indizierung für die Abfrage ist, die Sie ausführen möchten, oder Einstellungen mit Sortierpuffern).
Wenn Sie einen Index für die Spalte haben, sollte die Verwendung von DISTINCT
effizient sein. Wenn Sie dies nicht tun, ist ein vollständiger Tabellenscan erforderlich, um die einzelnen Zeilen abzurufen. Wenn Sie versuchen, die einzelnen Zeilen in PHP anstatt in MySQL zu sortieren, dann übertragen Sie (potentiell) viel mehr Daten von MySQL nach PHP, und PHP verbraucht viel mehr Speicher, um all diese Daten zu speichern, bevor die Duplikate eliminiert werden.
Hier ist eine Beispielausgabe von einer Dev-Datenbank, die ich habe. Beachten Sie außerdem, dass sich diese Datenbank auf einem anderen Server im Netzwerk befindet, von dem aus die Abfragen ausgeführt werden.
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 |
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+
Wenn ich die gleiche Abfrage versuchen, mit Ausnahme der SerialNumber
Spalte mit einer ersetzen, die nicht indiziert ist, dann dauert es ewig zu laufen, weil MySQL alle 97 Millionen Zeilen zu untersuchen hat.
Ein Teil der Effizienz hat damit zu tun, wie viele Daten Sie erwarten. Wenn ich die obigen Abfragen leicht modifiziere, um auf der time
Spalte (dem Zeitstempel des Lesens) zu arbeiten, dann dauert es 1 min 40 Sekunden, um eine deutliche Liste von 273,505 mal zu erhalten, der meiste Overhead besteht darin, alle Datensätze über die zu übertragen Netzwerk. Berücksichtigen Sie daher die Grenzen für die Datenmenge, die Sie zurückerhalten, und zwar so niedrig wie möglich für die Daten, die Sie abrufen möchten.
Was Ihre letzte Abfrage:
select distinct line from car_cache
where year='$postyear' and make='$postmake'
order by line desc
Es sollte mit, dass entweder kein Problem sein, so stellen Sie sicher, dass Sie eine Verbindung Index auf year
und make
und möglicherweise einen Index auf line
haben.
Ein letzter Punkt, der Motor I für die Lesungen Tabelle verwende ist InnoDB, und mein Server ist: 5.5.23-55-log Percona Server (GPL), Release 25.3
die
Hoffnung, eine Version von MySQL von Percona Inc. ist, das hilft.
Für die endgültige Abfrage wäre der beste Index entweder '(Jahr, machen, Linie)' oder '(machen, Jahr, Linie)' –
große gründliche Antwort konnte nicht besser bitten danke :) – Wolfe