평등에서만 선택하는 응용 프로그램이 있으며 btree 인덱스 위에 해시 인덱스를 사용해야한다고 생각합니다. 당황스럽게도 MyISAM 또는 InnoDB에서는 해시 인덱스가 지원되지 않습니다. 무슨 일이야?
평등에서만 선택하는 응용 프로그램이 있으며 btree 인덱스 위에 해시 인덱스를 사용해야한다고 생각합니다. 당황스럽게도 MyISAM 또는 InnoDB에서는 해시 인덱스가 지원되지 않습니다. 무슨 일이야?
답변:
많은 데이터베이스는 해시 기반 인덱스 를 전혀 지원하지 않습니다 .
해시 테이블을 효율적으로 사용하려면 존재할 가능성이있는 행 수를 알아야합니다. 그렇지 않으면 기본 해시 테이블이 너무 크거나 (많은 빈 항목, 공간 낭비 및 잠재적으로 디스크 IO) 또는 너무 작은 의미가됩니다. 간접적으로 사용되는 경우가 종종 있습니다 (여러 수준의 간접적 가능성, 또는 해시 구현이 단일 수준 인 경우에는 더 나빠질 수 있습니다).이 시점에서 트리 기반보다 더 효율적이지 않은 지점에서 선형 검색을 수행 할 수 있습니다. 어쨌든 색인.
따라서 일반적으로 유용하기 때문에 (일반적으로 대안보다 낫습니다.) 데이터가 커지거나 줄어듦에 따라 인덱스를 가끔씩 다시 작성해야하므로 상당한 간헐적 인 오버 헤드가 발생할 수 있습니다. 일반적으로 메모리 기반 테이블의 경우 재 구축이 꽤 빠르기 때문에 (데이터가 항상 RAM에 있고 어떤 경우에도 방대하지 않기 때문에) 디스크에 큰 인덱스를 다시 작성하는 것이 좋습니다. 매우 무거운 작업 (그리고 IIRC mySQL은 라이브 인덱스 재 구축을 지원하지 않으므로 작업 중에 테이블 잠금을 유지합니다).
따라서 해시 인덱스는 일반적으로 성능이 좋을수록 메모리 테이블에 사용되지만 디스크 기반 테이블은 보너스가 아닌 성능을 저하시킬 수 있으므로 테이블을 지원하지 않습니다. 물론 디스크 기반 테이블에 대해 해시 인덱스를 사용할 수있게하는 것은 아무것도 없습니다. 의심 할 여지없이 일부 데이터베이스 는 이 기능을 지원하지만, 관리자는 추가 기능을 고려하지 않으므로 ISAM / InnoDB 테이블에서는 구현되지 않을 것입니다. 작성하고 유지 관리하는 추가 코드는 몇 가지 상황에서 큰 차이를 만드는 이점이 없습니다). 아마도 당신이 강하게 동의하지 않는다면 그들과 이야기하고 그 기능을 구현하기에 좋은 사례를 만들 수 있습니다.
큰 문자열을 인덱싱하는 경우 값의 해시를 저장하고 실제 값을 갖는 인덱싱하여 자체 의사 해시 인덱스를 구현하면 작동 할 수 있지만 큰 문자열 (확실히있는 곳)에 대해서만 더 효율적입니다 해시 값을 계산 하고이 값으로 트리 인덱스를 검색하는 것이 항상 더 빠를 가능성이 높으며 비교를 위해 더 큰 값을 사용하여 트리 인덱스를 검색하는 것만으로 사용되는 추가 스토리지가 중요하지 않습니다.) 구현하기 전에 성능 분석을 수행하십시오. 이것은 생산에 있습니다.
관련 메모에서 PostgreSQL 문서의 인덱스 유형에 대한 토론이 흥미로울 수 있습니다. 최신 버전의 문서에는 더 이상 존재하지 않지만 (다음 최적화로 인해), 테이크 아웃은 MySQL과 비슷할 수 있습니다 (해시 인덱스가 힙 테이블에만 사용되는 이유).
http://www.postgresql.org/docs/8.1/static/indexes-types.html
참고 : 테스트에 따르면 PostgreSQL의 해시 인덱스가 B- 트리 인덱스보다 더 나은 성능을 발휘하지 못했으며 해시 인덱스의 인덱스 크기와 빌드 시간이 훨씬 나쁩니다. 또한 해시 인덱스 작업은 현재 WAL로 기록되지 않으므로 데이터베이스 충돌 후 REINDEX를 사용하여 해시 인덱스를 다시 작성해야 할 수도 있습니다. 이러한 이유로 해시 인덱스 사용은 현재 권장되지 않습니다. 마찬가지로, R- 트리 인덱스는 GiST 인덱스의 동등한 작업과 비교할 때 성능상의 이점이없는 것 같습니다. 해시 인덱스와 마찬가지로 WAL 로그가 아니며 데이터베이스 충돌 후 다시 인덱싱해야 할 수도 있습니다. 해시 인덱스의 문제는 결국 수정 될 수 있지만 향후 릴리스에서는 R- 트리 인덱스 유형이 폐기 될 수 있습니다. R- 트리 인덱스를 사용하는 응용 프로그램을 GiST 인덱스로 마이그레이션하는 것이 좋습니다.
다시 말하지만, PostgreSQL 전용 (구식 버전)이지만 "자연스러운"인덱스 유형이 반드시 최적의 성능을 제공하지는 않는다는 것을 암시해야합니다.
흥미로운 점이 있습니다.
책 MySQL 5.0 Certification Study Guide , 페이지 433, 섹션 29.5.1에 따르면
MEMORY 엔진은 기본 색인 알고리즘으로 HASH를 사용합니다.
웃음을 위해 MySQL 5.5.12에서 HASH를 사용하여 기본 키로 InnoDB 테이블과 MyISAM 테이블을 만들려고했습니다.
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은 불평하지 않았다.
최신 정보
나쁜 소식 !!! SHOW INDEXES FROM을 사용했습니다. 인덱스는 BTREE입니다.
는 INDEX 구문은 MySQL의 페이지 생성 에만 MEMORY 및 NDB 스토리지 엔진은 HASH 인덱스를 수용 할 수 있다고.
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)
어떤 사람들 은 해시 알고리즘을 에뮬레이트하기 위해 " 고성능 MySQL : 최적화, 백업, 복제 등 "책 102-105 페이지 의 아이디어 를 따르는 것이 좋습니다 .
Page 105 내가 좋아하는이 빠르고 더러운 알고리즘은 다음과 같습니다.
SELECT CONV(RIGHT(MD5('whatever value you want'),16),16,10) AS HASH64;
임의의 테이블에서이 열을 작성하고이 값을 색인화하십시오.
시도 해봐 !!!