Nasıl bu MySQL sorgusu optimize edebilirsiniz?

7 Cevap php

(Evet, 370.000.000) 370.000.000 satırlar üzerinde içeren bir veritabanı üzerinde bir PHP komut dosyası aşağıdaki MySQL sorgusu kullanıyorum. Ben son derece yoğun bir kaynak olduğunu biliyoruz ve bu bir sorgu çalıştırmak için yaş alır. Herkes Ben de daha hızlı olan başka bir şekilde sorgu optimize veya bilgi alabilirsiniz biliyor mu?

Table Info:

games | longint, unsigned, Primary Key
win   | bit(1)
loss  | bit(1)

Query:

SELECT MID(game,{$len},1) AS move,
       COUNT(*) AS games,
       SUM(win) AS wins,
       SUM(loss) AS losses
FROM games
WHERE game>{$something} AND game<{$something_else}
GROUP BY move

Yardımlarınız için şimdiden teşekkürler!

7 Cevap

Ben yapabilir sadece öneri tüm counts ön hesaplama için bir tabloyu kullanın ve sums her oyun için ve masa game, bir tetik kullanılarak değiştiğinde güncelleştirmek için.

Düz yarasa kapalı, ben SELECT ifadesi ve GROUP BY hem de MID () sorgusu kullanarak durdurmak olacaktır. En azından bu deneyin böylece sorgu koşullarına derinleşmesi, MySQL mutlaka ayrıştırma iken tek bir ifade içinde bu önbelleğe olmaz:

SELECT MID(game,{$len},1) AS move,
   COUNT(*) AS games,
   SUM(win) AS wins,
   SUM(loss) AS losses
   FROM games WHERE game LIKE '{$game}%' GROUP BY move;

Değil büyük, dünyanın değişim, ama küçük bir fark yapmak gerekir. Bunun dışında olsa da, ben ikinci verileri depolamak biçimini değiştirerek bu kısa optimize etmek için tek gerçek yol bu değerleri ön hesaplama ve oyun tamamlandığında bunları artırmak olduğunu.

Ben EXPLAIN query or profiling ile başlayan çalışacaktı.

Eğer ağır okumak ediyorsanız, tutmak düşünün ve sık sorgulamak veriler üzerinde toplu bir tablo korumak.

Bu denormalize ve bir "hamle" tablo oluşturmak, "Hamle" per kayıt istatistikler, yalnızca "oyun" per olabilir gibi geliyor bana.

Depolama alanı veya onserve depolama alanı ödün tarafından "hız almak" ama kötü performansı var olabilir. Sorunun hızı gibi, bazı precalculations gerekir. Ve evet, sorguda bazı profil.

BTW, "büyük olanlar" OLTP (gerçek zamanlı fiili işlemleri sunan) ve DW için farklı yapılandırmaları (farklı donanım ve ayarlar) (büyük miktarda veri analiz) için kullanılır.

The mid() function is what is killing this query. MySQL has to create a temp table in memory to deal with the mid() function and do filesort on that table because of the group by.

Ben $ oyun oyun türü olduğunu varsayarak yaşıyorum. (Dama, satranç, tic tac toe)

Ben oyunun türü için başka bir tablo asmak istiyorum. Bu grup çok daha hızlı olacağını bir dizin yararlanmak için izin verir.

Ben gibi bir şey öneririm:

[game]
game bigint unsigned
win bit
loss bit
game_type_id bigint unsigned

[game_type]
game_type_id bigint unsigned
game_type_desc varchar(13)

Be careful with alters statements on a table this large. Always make a backup before you issue an alter.