MySQL için Tepegöz SEÇER - Daha iyi Bir veya Dizi Birçok kullanın

3 Cevap php

Kerede gelen birini 500 satırları döndürür SELECT foo, bar, FROM users sorgu ve 500 SELECT foo, bar, FROM users WHERE id = x sorguları olan arasında kayda değer bir performans farkı var mı?

Ben yazıyorum bir PHP uygulamasında, ben yaklaşık 500 SELECT ifadeleri üretecek bir kod yazma açık, okunabilir bölüm arasında seçim çalışıyorum; veya 500 satır döndürür yalnızca birini kullanmak istiyorsunuz bir karanlık, karmaşık bir şekilde yazma.

Ben açık, sıçramalı kodu kullandığı yolu tercih ediyorum, ama ben SELECTleri her biri için bağlantı havai performans sorunlarına neden olacağını endişeleniyorum.

Background info, in case it's relevant: 1) This is a Drupal module, coded in PHP 2) The tables in question get very few INSERTs and UPDATEs, and are rarely locked 3) SQL JOINs aren't possible for reasons not relevant to the question

Teşekkürler!

3 Cevap

Bu SEÇ bir büyük toplu yapmak ve bir satır için SELECTleri büyük bir miktar yapıyor daha uygulama kodunuzda sonuçlarını ayrıştırmak için hemen hemen her zaman hızlı. Ben olsa, hem de uygulamak ve onları profile öneriyoruz. Her zaman yapmak zorunda varsayımlar sayısını en aza indirmek için çalışıyoruz.

Ben her sorgu arasındaki bağlantıyı kapatmadan değil, özellikle eğer, çok fazla mysql sorgularının bağlantı yükü dert olmaz. Sorgunuz geçici bir tablo oluşturursa, zaten aldı sorgu yükü daha sorguda daha fazla zaman geçirdim düşünün.

Ben şahsen karmaşık bir SQL sorgusu yapıyor seviyorum, ama ben tabloların boyutu, mysql sorgu önbellek ve tüm aralığı denetimi (hatta bir dizin karşı) yapmanız gereken sorguları sorgu performansını bir fark bulduk.

Ben bu öneririz:

1) Establish the simple, correct baseline. Ben bu trilyonlarca sorgu yaklaşım olduğunu sanıyorum. Bu helfully, doğru yanlış, ve çok olası değildir. Bunu birkaç kez çalıştırın ve sorgu önbelleği ve uygulama performansını izlemek. App bakımı tutmak için yeteneği diğer kod bakıcılarına ile çalışmak, özellikle çok önemlidir. Eğer gerçekten büyük tabloları sorgulama eğer Ayrıca, küçük sorgular ölçeklenebilirlik koruyacaktır.

2) Code the complex query. o zaman doğruluk sonuçları karşılaştırın, ve. Ardından kullanım taranan satır ne olduğunu görmek için sorguyu BEKLİYORUZ. Ben genellikle her zaman güncel vurmayacak bir tabloda ben, özellikle ben bir JOIN veya bir WHERE x! = Y, ya da geçici bir tablo oluşturur bir durum varsa, sorgu performansı oldukça kötü alabilir bulduk. Ancak, ben de karmaşık bir sorgu bir uygulama büyüdükçe karmaşık bir sorgu daha kolay kırılabilir bu da doğru değil, diye buldum. Karmaşık sorgular genellikle sık sık geçici tablolar oluşturma, satır büyük setleri tarama ve using where tarar çağırmak. Tablo daha büyük, daha pahalı bu olsun. Ayrıca, karmaşık sorgular ekibinizin güçlü uymayan takım hususlar var olabilir.

3) ekibi ile sonuçlarını paylaşın.

Karmaşık sorguları mysql sorgu önbelleği vurmak için daha az olasıdır, ve onlar yeterince büyükse, bunları önbelleğe yok. (Sık sık sorguları vurmak için mysql sorgu önbelleği kaydetmek istiyorum.) Ayrıca, indeks taramak zorunda yüklemleri de yapmayacağım sorgu. (X! = Y, x> y, x SELECT foo, bar FROM users WHERE foo != 'g' and mumble < '360' taramaları yapıyor sonunda. (Sorgu havai maliyeti bu durumda önemsiz olabilir.)

Küçük sorgular sıklıkla tam sadece, dizin tüm değerleri almak çok uzun alanlar olarak seçiyoruz ve üzerinde predicating tarafından geçici tablo oluşturma olmadan endeksli olabilir. Yani sorgu performans SELECT foo, bar FROM users WHERE id = x gerçekten büyük (esp sütunlar foo ve bar gibi aka alter table users add index ix_a ( foo, bar );. Endeksli)

Uygulamanızda performansını arttırmak için diğer iyi yolları (uygunsa) uygulamasında bu küçük sorgu sonuçlarını önbelleğe olmak, ya da bir hayata bakış sorgunun toplu iş yapıyor olurdu. Ayrıca, memcached veya XCache bulunan bazı özelliklere düşünün.

Eğer 500 id değerlerin ne biliyorum, neden böyle bir şey yapmak değil gibi görünüyor:

// Assuming you have already validated that this array contains only integers
// so there is not risk of SQl injection

$ids = join(',' $arrayOfIds);

$sql = "SELECT `foo`, `bar` FROM `users` WHERE `id` IN ($ids)";