SELECT * neden SELECT foo'dan daha hızlıdır?


28

Bunun gibi değerler ve kareler tablosunu göz önünde bulundurun:

+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| val        | char(9)  | NO   |     | NULL    |                |
| val_hashed | char(50) | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+

Aşağıdaki sorgu 0.00 saniye içinde bitiyor:

SELECT * FROM hashes ORDER BY 1 DESC LIMIT 1;

Ancak, bu sorgu 3 dakika 17 saniye sürer:

SELECT val FROM hashes ORDER BY 1 DESC LIMIT 1;

Sorgu çalışırken işlem listesinin durum olarak gösterildiğini görüyorum Sorting result. Durum tamamen tekrarlanabilir. INSERTMasada sürekli işlem yapan başka bir işlem olduğunu unutmayın .

Neden daha spesifik olan sorgunun sorgundan daha uzun sürmesi gerekiyor *? *Sorguların özellikle performans nedeniyle kaçınılması gerektiğine her zaman inandım .


7
İlk ifadeler muhtemelen idilk satırı bulmak için birincil anahtar dizinini kullanır . İkincisi, (endekslenmemiş) valsütunundaki sonucun tamamını sıralamalıdır .
a_horse_with_no_name

8
ORDER BY NUMBERSözdizimi oldukça yatkın hatadır.
usr

2
Son yorumunuza, SELECT *sütun dizini eklendiğinde, ORDER BYhangi sütunun sıralandığını engelliyor - *s'den kaçınmak için başka bir neden ...
lc.

# Ne demek istiyorsun?
Pacerier

@Pacerier *Açıkça değil demek istiyorum . Yani şeklindeki deterministik olarak "süpermarkete gidip birçok trafik geçirilen ışıklar nasıl söyle" hakkındadır "üçte bir oranında sıralama bana tüm sütunları verip" diyerek
lc.

Yanıtlar:


33

İfade ORDER BY 1, farklı sütunlara atıfta bulunur; Birincisinde id, ikincisinde olacak val. Yana ido endeksli olacak anahtardır ve order byişin önemsiz bir miktar olacaktır. İçin order by val, ancak, sistem her satır, göre sıralama komple tablo almak zorunda kalacak valdaha sonra bu satırların sadece birini seçmek.

Her iki sorguyu da değiştirin order by idve yürütme sürelerinizin neredeyse aynı olacağını düşünüyorum.


3
Bazen en zor sorular, suratımıza sadece bakan sorulardır. Sağol Michael!
dotancohen

7

Sorgunuzdaki performans farkı, MG tarafından iyi açıklanmıştır. Bunu ele alacağım:

Performans sebeplerinden dolayı * sorgulardan kaçınılması gerektiğine her zaman inandım.

select *tek başına belirli cezalar içermez, kötüye kullanıldığında sorunludur. Tek tablolu bir sorguda sadece iyi çalışıyor. şimdi bu tabloyu 20 sütuna sahip bir başkasına birleştirin ve daha sonra her biri birçok sütuna sahip diğer 5 tabloya birleştirme ekleyin. ŞİMDİ bu bir problem. Yani, geniş, yara bandı öğreten insanlar, nedenini açıklamadan "asla X yapmazlar".


3
SELECT *Tek tablolu bir sorgu için bile bir sorun olabilir. Örneğin, SELECT * FROM hashes ORDER BY val;muhtemelen tam bir tablo taraması yapacak ve daha sonra bir sıralama SELECT val FROM hashes ORDER BY val;yalnızca tam bir dizin taraması yapacak ve sıralama yapmayacak (bir dizinin val'de olduğu varsayılarak). Bu nedenle, sadece ihtiyacımız olan sonuçları seçmek asla zarar vermez.
ypercubeᵀᴹ


@ypercube, Bizim select(*)sadece alt seçim olarak kullanılsa bile olur mu? Gömülü bir seçim olduğundan, MySQL'in seçilmesi gereken gerçek sütunları bulabilecek kadar akıllı olmaz mıydı?
Pacerier

@Pacerier mysql optimizer, kullandığınız sürüme bağlı olarak farklı "akıllılık" seviyelerine sahiptir. Gerneal'da iç içe geçmiş sorgularla ilgili oldukça aptaldı, bu yüzden ona yardım edebilecekleriniz iyi oldu.
ypercubeᵀᴹ

@ ypercube, Ah, sadece pgsql kadar akıllıysa.
Pacerier
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.