2013-07-17 14 views
6

mySQL tablomun dizini kullanmam dizini kullanmıyor ve nedenini bilmiyorum.Çok basit mysql sorgu dizini kullanmadı

CREATE TABLE IF NOT EXISTS `test` (
    `a` int(11) NOT NULL, 
    `b` int(11) NOT NULL, 
    KEY `kk` (`a`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

ve bu:

bende

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE  test ALL NULL   NULL NULL NULL 10009 Using filesort 
: Bu

EXPLAIN SELECT * 
FROM test 
USE INDEX (kk) 
ORDER BY a 

yanı sıra

EXPLAIN SELECT * 
FROM test 
ORDER BY a 

bana bu verir

Bu dosya grubunu görmek istemiyorum ve tablomu sıralamak için anahtar kk tuşunu kullanın. Neyi yanlış yapıyorum?


Mesajlarınız için teşekkürler arkadaşlar, onlar sorumu yanıtlıyorlar! Ancak, şimdi "tablo taraması" ve "filesort" ile ne anlama geldiğini kastetmiyorum? Tüm alanları ve bir tablonun tüm satırlarını seçmeme rağmen, o tablonun O (n) dizinindeki iç ağacını (ve sonra tabloya bakarak) tek bir sütunla sıralamak daha hızlı değil mi? İstenen ekstra sütunları dosyaya, her satır için O (1) 'de => dizin dosyası her satırın fiziksel konumunu tablo dosyasında ya da?) indeksine dokunmadan tablo dosyasındaki O (n * log n) (potansiyel olarak) rastgele saklanan satırları hızlı bir şekilde sıralayarak? İndekslerin mySQL'de nasıl çalıştığına dair anlayışım yanlış. o tam tarama kullanmak daha verimli olmasını MySQL tahminleri -

cevap

11
  1. Sen yukarıda söylediklerini takiben tüm sütunları

seçiyoruz

  • tüm satırları seçerek ediyoruz.

    o dizini kullanarak almak için, satır makul sayıya sınırlayacak bazı WHERE eklemeniz gerekir döndü (diyelim 50)

  • +0

    Yani "tüm satırlar" 1), değil mi? –

    +0

    @a_horse_with_no_name: Muhtemelen "tüm tabloyu" (veya "tüm satırları") kastediyorum. İngilizceyi doğru bir şekilde nasıl ifade ettiğinden emin değil. – zerkms

    +1

    Evet, "tüm tablo" veya "tüm satırlar" daha iyi olurdu. –

    0

    beri var hayır WHERE yan tümcesi bir filesort (tablo taraması) yapacak sürece Seçtiğiniz sadece öğe endeksten. Bu sorgu dizini kullanacaktır. Dizinde bir sütun değil seçmek (* veya b) Bir dosya taraması yapacak Ancak bu SQL Fiddle

    EXPLAIN SELECT a FROM test ORDER BY a 
    

    bakınız. Ya kaplama dizinine sahip bir cümle ekleyin ya da seçtiğiniz sütunları değiştirin.

    2

    @zerkms doğrudur, tablodaki tüm satırları okuyarak, MySQL tablonun çoğunluğunu okumak zorunda kalacağına karar verir, böylece dizini okumaya gerek yoktur. Tablonun bir alt kümesini seçerseniz, en iyileştirici davranışı değiştirir.

    Örneğin, sizinki gibi bir tablo oluşturdum ve 0 ve 1000000 arasında rastgele tamsayılarla 16384 satır doldurdum. Daha sonra tablonun farklı alt kümeleri için EXPLAIN'i denedim, tablonun ilk% 15'i, sonra% 17, o zaman% 19.

    mysql> EXPLAIN SELECT * FROM test where a < 150000 ORDER BY a; 
    +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
    +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
    | 1 | SIMPLE  | test | range | kk   | kk | 5  | NULL | 2272 | Using where | 
    +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
    
    mysql> EXPLAIN SELECT * FROM test where a < 170000 ORDER BY a; 
    +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
    +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
    | 1 | SIMPLE  | test | range | kk   | kk | 5  | NULL | 2560 | Using where | 
    +----+-------------+-------+-------+---------------+------+---------+------+------+-------------+ 
    
    mysql> EXPLAIN SELECT * FROM test where a < 190000 ORDER BY a; 
    +----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+ 
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra      | 
    +----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+ 
    | 1 | SIMPLE  | test | ALL | kk   | NULL | NULL | NULL | 16384 | Using where; Using filesort | 
    +----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+ 
    

    Ayrıca sadece endeksinin sütunları seçerek kadar sütunları azaltarak endeksi kullanmak için ikna edebilirsiniz. Yalnızca dizini okumaya karar verir ve tabloya dokunmaz. Gerekirse, bu sütunlar arama veya sıralama için gerekli olmasa bile, ek sütunlar içeren bir dizin tanımlayabilirsiniz.

    mysql> ALTER TABLE test ADD KEY kk2 (a,b); 
    mysql> EXPLAIN SELECT a,b FROM test ORDER BY a; 
    +----+-------------+-------+-------+---------------+------+---------+------+-------+-------------+ 
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
    +----+-------------+-------+-------+---------------+------+---------+------+-------+-------------+ 
    | 1 | SIMPLE  | test | index | NULL   | kk2 | 10  | NULL | 16384 | Using index | 
    +----+-------------+-------+-------+---------------+------+---------+------+-------+-------------+