Oku birden fazla kayıt verimli veritabanından kayıt kimlikleri dizi verilen

5 Cevap php

Eğer uygulama kodu içinde rekor bir dizi kimlikleri varsa, veritabanından kayıtları okumak için en iyi yolu nedir?

$idNumsIWant = {2,4,5,7,9,23,56};

Eğer n sorgular çünkü Açıkçası her ID üzerinde döngü kötü:

foreach ($idNumsIWant as $memID) {
    $DBinfo = mysql_fetch_assoc(mysql_query("SELECT * FROM members WHERE mem_id = '$memID'"));
    echo "{$DBinfo['fname']}\n";
}

Yani, belki de tek bir sorgu kullanmak daha iyidir?

$sqlResult = mysql_query("SELECT * FROM members WHERE mem_id IN (".join(",",$idNumsIWant).")");
while ($DBinfo = mysql_fetch_assoc($sqlResult))
  echo "{$DBinfo['fname']}\n";

Ama dizi 30.000 elementler bu yöntem ölçek vardır ne zaman?

Bu sorunu nasıl verimli mücadele ediyoruz?

5 Cevap

En iyi yaklaşım, (tabii ki teknik olarak çok sayıda sorun olmadan onunla ilgili yeteneğine sahip olsa bile, sunucuya bir 50MB SQL sorgusu göndermek istemiyorum) Eğer dizideki var kimlikleri sayısına sonunda bağlıdır, ancak çoğunlukla çıkan satır başa gidiyoruz nasıl.

  • Kimlikleri sayısı çok düşükse, (Şimdi birkaç bin üstleri diyelim) IN sözdizimini kullanarak fıkra mükemmel olacak WHERE bir tek sorgu. Bu DB sunucuya verimli ve hızlı, güvenilir bir transfer olmak için SQL sorgusu kadar kısa olacaktır. Bu yöntem, elde edilen kayıtlar döngü tek bir iş parçacığı için idealdir.

  • Kimlikleri sayısı gerçekten büyük ise, ben size birkaç grupta kimlikleri dizi bölünmüş öneririz, ve daha 1 sorgusu, kimlikleri bir grup ile her biri çalışır. Bu DB sunucu için biraz ağır olabilir, ancak uygulama tarafında çeşitli konuları spawn ve en kısa sürede bir PARRALLEL şekilde gelmesi gibi çoklu kayıt anlaşma.

Her iki yöntem çalışacaktır.

CliffNotes: durumlarda bu tür için, sürece veri çıkarma, bir darboğaz çok büyük değil gibi, veri kullanımı odaklanmak. Ve app profili!

Düşüncelerim:

İlk yöntem, işlem açısından çok pahalı olan ve disk okur.

İkinci yöntem daha etkili olduğunu ve query size limit hakkında çok fazla endişelenmenize gerek (ama yine de kontrol edin) yoktur.

Ben durumun bu tür uğraşmak zorunda, ben en az üç ya da dört olası çözümleri bakın:

  • id başına bir istek; Dediğin gibi, bu gerçekten iyi değil: istekleri çok; Ben genelde yapmayın
  • use the solution you proposed : one request for many ids
    • ancak kimlikleri çok uzun bir liste ile bunu yapamazsınız: bazı veritabanı motorları bir IN() iletebilirsiniz veri sayısının bir sınırı var
    • çok büyük bir liste IN() iyi performans akıllıca olmayabilir
    • Yani genellikle X kimlikleri için bir istek gibi bir şey yapmak ve bu tekrarlayın. Örneğin, 1000 kimlikleri karşılık gelen verileri fecth, ben 20 istekleri yapabilirim, 50 kimlikleri için her veri alma (that's just an example : benchmarking your DB/table could be intresting, for your particular case, as it might depends on several factors)
  • Bazı durumlarda, aynı zamanda isteklerini yeniden düşünebiliriz: Belki bir çeşit birleşim kullanarak, kimlikleri böyle bir liste geçen önlemek olabilir? (this really depends on what you need, your tables' schema, ...)

Ayrıca, getiriliyor mantık değişiklikleri kolaylaştırmak için, ben kimlikleri listesini alır bir işlev yazmak ve bu karşılık gelen verilerin listesini dönecekti.

Bu şekilde, sadece bu fonksiyonu aynı şekilde aramak ve her zaman bu veri getirilen nasıl düşünmek zorunda değil, aynı verileri almak; NASIL fonksiyon çalışmaları değişecek, ancak arayüz olarak (giriş / çıkış) böyle olmaz, aynı kalır: Bu şey bozmadan, gerekirse (bazı gün başka daha iyi bir yol bulmak ise) getiriliyor yöntemini değiştirmek için izin verir :-) kodunuzun geri kalanı için bir şey değişmez

Beni ve ben olsaydı bunun için değerlerin büyük bir listesini yan tümcesinde, ben istediğim değerleri içeren bir değişken ile bir saklı yordam kullanmak ve bir geçici tabloya göndermek içinde bir işlevi kullanmak ve sonra ona katılmak . Göndermek istediğiniz değerler boyutuna bağlı olarak, işlemek için mutiple giriş vairables içine bölmek gerekebilir. (Genellikle bu sorgulayarak varsa) değerleri kalıcı veritabanında saklanır herhangi bir yolu var mı? Ve nasıl bir kullanıcı kesinlikle o n, 30.000 değerlerini ortaya çıkarmak için gidiyor; t hepsini tyope olacak? Yani katılmak ona dayalı tablosunu sorgulamak için daha iyi bir yolu ve bir fıkra muhtemelen vardır.

U birden çok değer için veri alma, bu işlemek için daha kolay olurdu belirteçleri içine dize ayırarak StringTokenizer kullanma