Sadece eşitliği seçecek bir uygulamam var ve btree endeksi üzerinde karma endeksi kullanmam gerektiğini düşünüyorum. Benim dezavantajım için, hash endeksleri MyISAM veya InnoDB'de desteklenmiyor. Bunun nesi var?
Sadece eşitliği seçecek bir uygulamam var ve btree endeksi üzerinde karma endeksi kullanmam gerektiğini düşünüyorum. Benim dezavantajım için, hash endeksleri MyISAM veya InnoDB'de desteklenmiyor. Bunun nesi var?
Yanıtlar:
Birçok veritabanları karma bazlı endeksler desteklemeyen hiç .
Bir karma tablosunun verimli olması için, mevcut olması muhtemel olan satır sayısını bilmeniz gerekir, aksi takdirde temel karma tablosu çok büyük (çok fazla boş giriş, boşa harcanan ve potansiyel olarak disk GÇ) veya çok küçük olacaktır dolaylı kullanım çoğu zaman kullanılır (muhtemelen birden fazla dolaylı seviye veya karma uygulama tek seviyeli ise daha da kötüsü, bir noktada ağaç temelli bir ağaçtan daha verimli olmayan bir noktada, çok sayıda kayıt üzerinde doğrusal bir arama yaparak sonuçlanabilir) Yine de indeksleyin.
Bu nedenle, genellikle yararlı olması için (yani genellikle alternatiften daha iyi), önemli ölçüde aralıklı bir ek yük ekleyebilecek veri büyüdükçe (ve daraştıkça) endeksin zaman zaman yeniden oluşturulması gerekir. Yeniden oluşturma muhtemelen oldukça hızlı olacağından (veriler her zaman RAM’de olacağından ve her durumda büyük olasılıkla büyük olasılıkla olmadığından) bu genellikle bellek tabanlı tablolarda iyidir, ancak diskte büyük bir dizin oluşturmak çok ağır bir işlem (ve IIRC mySQL canlı indeks yeniden oluşturmalarını desteklemez, bu nedenle işlem sırasında bir masa kilidi tutar).
Bu nedenle, karma dizinler genellikle daha iyi performans gösterdikleri için bellek tablolarında kullanılır, ancak disk tabanlı tablolar, bonus değil performansa zarar verebileceği için bunları desteklemez. Elbette, disk tabanlı tablolar için kullanılabilir yapılıyor durdurma karma endeksler bir şey yok, hiçbir bazı veritabanları şüphe yapmak özelliği desteklemesi, ancak muhtemelen onlar ISAM uygulanmadı / maintainers'ı olarak InnoDB tablolar olarak özellik değerinde ekleme (düşünmüyoruz yazması ve sürdürmesi için ekstra kod, önemli bir fark yarattığı bu birkaç durumda faydaya değmez). Belki de kesinlikle katılmıyorsanız, onlarla konuşabilir ve özelliğin uygulanması için iyi bir dava açabilirsiniz.
Büyük dizeleri dizine ekliyorsanız, kendi sözde-karma dizinini uygularsanız (gerçek değerin yanı sıra, değerin bir karma değerini depolayarak da sütun içeren indeksleme) çalışabilir, ancak bu yalnızca büyük dizeler için daha verimlidir (burada karma değerinin hesaplanması ve ağaç endeksinin bu değer ile aranması her zaman daha hızlı olacaktır, daha sonra sadece karşılaştırma için daha büyük değerleri kullanarak bir ağaç endeksinin aranması ve kullanılan fazladan depolama alanı önemli olmayacaktır). bu üretimde.
İlgili bir notta, PostgreSQL dokümanlarından ilgi çekici endeks türleriyle ilgili tartışmaları bulabilirsiniz. Artık dokümanın son sürümlerinde mevcut değil (sonraki optimizasyonlar nedeniyle, bunu alıyorum), ancak paket servisi MySQL için benzer olabilir (ve karma dizinlerinin yalnızca yığın tabloları için kullanılmasının nedeni):
http://www.postgresql.org/docs/8.1/static/indexes-types.html
Not: Test Etme, PostgreSQL'in karma dizinlerini B ağacı dizinlerinden daha iyi performans göstermediğini gösterdi ve karma dizinler için dizin boyutu ve oluşturma süresi çok daha kötü. Ayrıca, karma dizin işlemleri şu anda WAL günlüğünde değildir, bu nedenle bir veritabanı çökmesinden sonra karma dizinlerin REINDEX ile yeniden oluşturulması gerekebilir. Bu nedenlerden dolayı, hash endeksi kullanımı halen önerilmemektedir. Benzer şekilde, R-ağacı endeksleri, GiST endekslerinin eşdeğer işlemlerine kıyasla hiçbir performans avantajına sahip görünmemektedir. Karma dizinler gibi, WAL günlüğüne kaydedilmemişlerdir ve bir veritabanı çökmesinden sonra yeniden indekslemeye ihtiyaç duyabilirler. Sonunda karma dizinleri ile ilgili sorunlar çözülebilse de, R-ağacı dizin türünün gelecekteki bir sürümde emekli olması muhtemeldir. Kullanıcılar, R-ağacı dizinlerini kullanan uygulamaları GiST dizinlerine geçirmeye teşvik edilir.
Yine, PostgreSQL'e özgü (eski sürüm), ancak "doğal" dizin türünün mutlaka en iyi performansı vermeyeceğini ima etmesi gerekir.
İşte ilginç bir şey:
Kitaba göre 5.0 Sertifikasyon Eğitim Kılavuzu MySQL , Sayfa 433, Bölüm 29.5.1
MEMORY motoru, varsayılan indeksleme algoritması tarafından HASH kullanır.
Gülmek için, MySQL 5.5.12’de HASH kullanarak bir InnoDB tablosu ve bir birincil anahtarla bir MyISAM tablosu oluşturmaya çalıştım.
mysql> use test
Database changed
mysql> create table rolando (num int not null, primary key (num) using hash);
Query OK, 0 rows affected (0.11 sec)
mysql> show create table rolando\G
*************************** 1. row ***************************
Table: rolando
Create Table: CREATE TABLE `rolando` (
`num` int(11) NOT NULL,
PRIMARY KEY (`num`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> create table rolando2 (num int not null, primary key (num) using hash) engine=MyISAM;
Query OK, 0 rows affected (0.05 sec)
mysql> show create table rolando2\G
*************************** 1. row ***************************
Table: rolando2
Create Table: CREATE TABLE `rolando2` (
`num` int(11) NOT NULL,
PRIMARY KEY (`num`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
MySQL şikayet etmedi.
GÜNCELLEME
Kötü haber !!! SHOW INDEXES FROM kullandım. Endeksin BTREE olduğunu söylüyor.
Index sözdizimi MySQL Sayfa CREATE tek BELLEK ve NDB depolama motorları HASH INDEX ağırlayacak belirtiyor.
mysql> show indexes from rolando;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| rolando | 0 | PRIMARY | 1 | num | A | 0 | NULL | NULL | | BTREE | | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
mysql> show indexes from rolando2;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| rolando2 | 0 | PRIMARY | 1 | num | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
mysql> create table rolando3 (num int not null, primary key (num)) ENGINE=MEMORY;
Query OK, 0 rows affected (0.03 sec)
mysql> show create table rolando3\G
*************************** 1. row ***************************
Table: rolando3
Create Table: CREATE TABLE `rolando3` (
`num` int(11) NOT NULL,
PRIMARY KEY (`num`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> show indexes from rolando3;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| rolando3 | 0 | PRIMARY | 1 | num | NULL | 0 | NULL | NULL | | HASH | | |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
Bazı insanlar , hash algoritmasını taklit etmek için " Yüksek Performanslı MySQL: Optimizasyonlar, Yedeklemeler, Çoğaltma ve Daha Fazlası " kitabının 102-105. Sayfalarındaki fikrini izlemeyi önerdi .
Page 105 beğendiğim bu hızlı ve kirli algoritmaya sahip:
SELECT CONV(RIGHT(MD5('whatever value you want'),16),16,10) AS HASH64;
Herhangi bir tabloda bunun için bir sütun yapın ve bu değeri indeksleyin.
Bir şans ver !!!
BTree, tek sıralı arama için Hash'den çok daha yavaş değildir. BTree çok verimli bir dizi sorgulama sağladığından, neden BTree'den başka bir şeyle uğraşmıyorsunuz?
MySQL, BTree bloklarını önbelleğe almak için çok iyi bir iş çıkarır, bu nedenle BTree tabanlı bir sorgu nadiren herhangi bir sorguda en büyük zaman tüketicisi olan G / Ç yapmak zorunda kalır.