ฉันมีแอพพลิเคชั่นที่จะเลือกใช้ความเท่าเทียมกันเท่านั้นและฉันคิดว่าฉันควรใช้ดัชนีแฮชเหนือดัชนี btree MyISAM หรือ InnoDB ไม่รองรับดัชนีแฮชของฉัน เกิดอะไรขึ้นกับสิ่งนั้น
ฉันมีแอพพลิเคชั่นที่จะเลือกใช้ความเท่าเทียมกันเท่านั้นและฉันคิดว่าฉันควรใช้ดัชนีแฮชเหนือดัชนี btree MyISAM หรือ InnoDB ไม่รองรับดัชนีแฮชของฉัน เกิดอะไรขึ้นกับสิ่งนั้น
คำตอบ:
ฐานข้อมูลจำนวนมากไม่สนับสนุนดัชนีตามกัญชาที่ทั้งหมด
เพื่อให้ตารางแฮชมีประสิทธิภาพคุณจำเป็นต้องทราบจำนวนแถวที่น่าจะมีอยู่มิฉะนั้นตารางแฮชพื้นฐานจะใหญ่เกินไป (รายการที่ว่างเปล่าจำนวนมากการสูญเสียพื้นที่และดิสก์ IO) หรือมีขนาดเล็กเกินไป ทางอ้อมมักใช้ (อาจมีหลายระดับทางอ้อมหรือแย่กว่านั้นหากการนำ hash มาใช้เป็นระดับเดียวคุณสามารถทำการค้นหาแบบเป็นเส้นตรงกับจำนวนเรคคอร์ดที่พอใช้) ซึ่งสิ่งต่าง ๆ อาจไม่มีประสิทธิภาพมากกว่าต้นไม้ จัดทำดัชนีต่อไป
ดังนั้นโดยทั่วไปจะมีประโยชน์ (เช่นมักจะดีกว่าทางเลือก) ดัชนีจำเป็นต้องสร้างใหม่เป็นครั้งคราวเมื่อข้อมูลเติบโต (และลดขนาดลง) ซึ่งสามารถเพิ่มค่าใช้จ่ายที่ไม่สม่ำเสมอเป็นระยะ นี้มักจะดีกับตารางตามหน่วยความจำเนื่องจากการสร้างอาจจะค่อนข้างเร็ว (เนื่องจากข้อมูลมักจะอยู่ใน RAM และไม่น่าจะมีขนาดใหญ่ในทุกกรณี) แต่การสร้างดัชนีขนาดใหญ่บนดิสก์ใหม่ การทำงานหนักมาก (และ IIRC mySQL ไม่รองรับการสร้างดัชนีใหม่ดังนั้นจึงมีการล็อคตารางระหว่างการดำเนินการ)
ดังนั้นดัชนีแฮชจะถูกใช้ในตารางหน่วยความจำเนื่องจากโดยทั่วไปมักจะมีประสิทธิภาพที่ดีกว่า แต่ตารางที่ใช้ดิสก์ไม่สนับสนุนเนื่องจากอาจเป็นอันตรายต่อประสิทธิภาพไม่ใช่โบนัส ไม่มีอะไรที่จะจัดทำดัชนีกัญชาหยุดการทำใช้ได้สำหรับตารางตามดิสก์ของหลักสูตรคือไม่มีข้อสงสัยฐานข้อมูลบางอย่างทำสนับสนุนคุณลักษณะ แต่สันนิษฐานว่าพวกเขาจะไม่ดำเนินการใน ISAM / ตาราง InnoDB เป็นผู้ดูแลไม่ได้พิจารณามูลค่าคุณลักษณะเพิ่ม (ขณะที่ รหัสพิเศษสำหรับการเขียนและบำรุงรักษาไม่คุ้มค่ากับผลประโยชน์ในบางสถานการณ์ที่ทำให้เกิดความแตกต่างอย่างมีนัยสำคัญ) บางทีถ้าคุณไม่เห็นด้วยอย่างยิ่งคุณสามารถพูดคุยกับพวกเขาและทำให้เป็นกรณีที่ดีสำหรับการใช้งานคุณลักษณะ
หากคุณกำลังจัดทำดัชนีสตริงขนาดใหญ่ดังนั้นการใช้ดัชนีแฮชหลอกของคุณเอง (โดยการจัดเก็บแฮชของค่ารวมถึงค่าจริงและการจัดทำดัชนีที่มีคอลัมน์) อาจใช้งานได้ แต่จะมีประสิทธิภาพมากกว่าสำหรับสตริงขนาดใหญ่เท่านั้น การคำนวณค่าแฮชและค้นหาดัชนีต้นไม้โดยค่านี้มักจะเร็วกว่าจากนั้นเพียงแค่ค้นหาดัชนีต้นไม้โดยใช้ค่าที่ใหญ่กว่าสำหรับการเปรียบเทียบและหน่วยเก็บข้อมูลพิเศษที่ใช้จะไม่สำคัญ) จึงทำการวิเคราะห์ประสิทธิภาพก่อนดำเนินการ ในการผลิต
ในบันทึกที่เกี่ยวข้องคุณอาจพบการสนทนาเกี่ยวกับประเภทดัชนีจากเอกสาร PostgreSQL ที่น่าสนใจ มันไม่ได้อยู่ในเอกสารรุ่นล่าสุดอีกต่อไป (เนื่องจากการปรับแต่งตามมาฉันเอามันไป) แต่การซื้ออาจจะคล้ายกับ MySQL (และเหตุผลที่ดัชนีแฮชใช้สำหรับตารางฮีปเท่านั้น):
http://www.postgresql.org/docs/8.1/static/indexes-types.html
หมายเหตุ: การทดสอบได้แสดงดัชนีแฮชของ PostgreSQL เพื่อให้ทำงานได้ไม่ดีกว่าดัชนี B-tree และขนาดดัชนีและเวลาสร้างสำหรับดัชนีแฮชยิ่งแย่ลงมาก นอกจากนี้การดำเนินการดัชนีแฮชไม่ได้ถูกบันทึกใน WAL ในปัจจุบันดังนั้นดัชนีแฮชอาจต้องสร้างใหม่ด้วย REINDEX หลังจากฐานข้อมูลขัดข้อง ด้วยเหตุผลเหล่านี้ทำให้การใช้ดัชนีแฮชไม่ได้รับการสนับสนุนในขณะนี้ ในทำนองเดียวกันดัชนี R-tree ดูเหมือนจะไม่มีข้อได้เปรียบด้านประสิทธิภาพใด ๆ เมื่อเทียบกับการดำเนินการที่เทียบเท่าของดัชนี GiST เช่นเดียวกับดัชนีแฮชพวกเขาจะไม่ได้รับการบันทึก WAL และอาจต้องทำการทำดัชนีใหม่หลังจากฐานข้อมูลขัดข้อง ในขณะที่ปัญหาที่เกิดขึ้นกับดัชนีแฮชอาจได้รับการแก้ไขในที่สุดก็เป็นไปได้ว่าดัชนี R-tree จะถูกยกเลิกในอนาคต ผู้ใช้ควรโยกย้ายแอปพลิเคชันที่ใช้ดัชนี R-tree ไปยังดัชนี GiST
อีกครั้งเป็นรุ่นเฉพาะของ PostgreSQL แต่ควรบอกเป็นนัยว่าประเภทดัชนี "ธรรมชาติ" ไม่จำเป็นต้องให้ประสิทธิภาพที่ดีที่สุด
นี่คือสิ่งที่น่าสนใจ:
ตามหนังสือคู่มือการศึกษาการรับรอง MySQL 5.0 , หน้า 433, มาตรา 29.5.1
เอ็นจิ้น MEMORY ใช้ HASH โดยอัลกอริทึมการทำดัชนีเริ่มต้น
สำหรับหัวเราะฉันพยายามสร้างตาราง InnoDB และตาราง MyISAM ด้วยคีย์หลักโดยใช้ HASH ใน MySQL 5.5.12
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 ไม่ได้บ่น
UPDATE
ข่าวร้าย !!! ฉันใช้ SHOW INDEXES จาก มันบอกว่าดัชนีคือ BTREE
สร้างดัชนีไวยากรณ์ MySQL หน้าระบุว่ามีเพียงหน่วยความจำและเครื่องมือการเก็บรักษา NDB สามารถรองรับกัญชาดัชนี
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)
บางคนแนะนำให้ติดตามแนวคิดในหน้า 102-105 ของหนังสือ " MySQL ประสิทธิภาพสูง: การเพิ่มประสิทธิภาพการสำรองข้อมูลการจำลองแบบและอื่น ๆ " เพื่อจำลองอัลกอริทึมแฮช
หน้า 105 มีอัลกอริทึมที่รวดเร็วและสกปรกที่ฉันชอบ:
SELECT CONV(RIGHT(MD5('whatever value you want'),16),16,10) AS HASH64;
สร้างคอลัมน์สำหรับสิ่งนี้ในตารางใด ๆ และสร้างดัชนีค่านี้
ให้มันลอง !!!
BTree นั้นไม่ช้ากว่า Hash มากนักสำหรับการค้นหาแถวเดียว เนื่องจาก BTree มีข้อความค้นหาที่หลากหลายและมีประสิทธิภาพมาก
MySQL ทำงานได้ดีมากในการแคชบล็อก BTree ดังนั้นแบบสอบถามที่ใช้ BTree จึงไม่ค่อยต้องทำ I / O ซึ่งเป็นผู้ใช้เวลามากที่สุดในแบบสอบถามใด ๆ