2014-09-02 2 views
0

나는 하나의 테이블로 간단한 DB에 파일 해시 데이터를 저장하기 위해 MySQL을 사용하는 응용 프로그램을 작성하고 있습니다. (* 인덱스가있는 MySQL 성능이 느립니다 *?

SELECT * FROM hash_db.main_tbl WHERE 
     sha256 = '...' OR 
     sha1 = '...' OR 
     md5 = '...' 


INSERT INTO hash_db.main_tbl 
    (sha256, sha1, md5, created, modified, size, ext, path, new_record) VALUES 
    (
    '...'     , 
    '...'     , 
    '...'     , 
    FROM_UNIXTIME(...)  , 
    FROM_UNIXTIME(...)  , 
    ...      , 
    '...'     , 
    '...'     , 
    TRUE         
) 

데이터가 거의 랜덤과 고유성 확률이 매우 높다 없습니다 :

CREATE DATABASE IF NOT EXISTS hash_db; 

CREATE TABLE IF NOT EXISTS hash_db.main_tbl 
(          
    sha256  CHAR(64) PRIMARY KEY , 
    sha1   CHAR(40) UNIQUE KEY  , 
    md5   CHAR(32) UNIQUE KEY  , 
    created  DATETIME    , 
    modified  DATETIME    , 
    size   BIGINT     , 
    ext   VARCHAR(260)   , 
    path   TEXT(32768)    , 
    new_record BOOL      
)          
ENGINE = MyISAM 

CREATE UNIQUE INDEX sha256_idx ON hash_db.main_tbl (sha256) 
CREATE UNIQUE INDEX sha1_idx ON hash_db.main_tbl (sha1) 
CREATE UNIQUE INDEX md5_idx ON hash_db.main_tbl (md5) 

가 그럼 난 형태의 간단하게 선택하여 삽입을하고있어 다음과 같이 내가 만든 것 그것은 중요해야한다, 그렇지 않으면 안된다?). 첫 번째 질문, 그러한 사용에 대한의 MyISAM보다 (~ 느리게 7 배) 이노 훨씬 느린 것이 정상입니까? 나는 그것이 다른 길 (512M innodb_buffer_pool_size, 아무런 차이없이 시도)에 있어야한다고 읽었다.

두 번째 ... 내가 함께 인덱스 (의 MyISAM)과 인덱스 버전이 실제로 느립니다없이 테스트했습니다. C에서 성능 카운터를 사용하여 내 앱에서 측정 한 실제 성능 데이터입니다.

With indexes: 
Selects per second: 393.7 
Inserts per second: 1056.1 

Without indexes: 
Selects per second: 585.3 
Inserts per second: 1480.9 

데이터는 반복 가능합니다. 나는 확대 된 key_buffer_size (32M, 디폴트는 8M)로 테스트했다. 내가 잘못하고 또는 실종 무엇

?

============================================== ==================================

편집 고든 리노 프의 제안 후 : 내가 가지고있는

UNION ALL으로 시도한 결과 실제로 성능이 떨어지면서 초 당 70이 정확하게 선택되었습니다. 다음의 출력이 EXPLAIN 있다 : 저 (I는 'SHA1'항목에 대한 두 개의 별도의 인덱스를 작성 하였다) I 인덱스 생성에 오류가 발생한보고했다

EXPLAIN EXTENDED SELECT * FROM main_hash_db.main_tbl WHERE md5 = '...' 

+----+-------------+----------+-------+---------------+------+---------+-------+------+----------+-------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | 
+----+-------------+----------+-------+---------------+------+---------+-------+------+----------+-------+ 
| 1 | SIMPLE  | main_tbl | const | md5   | md5 | 97  | const | 1 | 100.00 | NULL | 
+----+-------------+----------+-------+---------------+------+---------+-------+------+----------+-------+ 


EXPLAIN EXTENDED SELECT * FROM main_hash_db.main_tbl WHERE md5 = '...' UNION ALL SELECT * FROM main_hash_db.main_tbl WHERE sha1 = '...' 

+----+--------------+------------+-------+-----------------------+------+---------+-------+------+----------+-----------------+ 
| id | select_type | table  | type | possible_keys   | key | key_len | ref | rows | filtered | Extra   | 
+----+--------------+------------+-------+-----------------------+------+---------+-------+------+----------+-----------------+ 
| 1 | PRIMARY  | main_tbl | const | md5     | md5 | 97  | const | 1 | 100.00 | NULL   | 
| 2 | UNION  | main_tbl | const | sha1,sha1_idx,md5_idx | sha1 | 121  | const | 1 | 100.00 | NULL   | 
| NULL | UNION RESULT | <union1,2> | ALL | NULL     | NULL | NULL | NULL | NULL |  NULL | Using temporary | 
+----+--------------+------------+-------+-----------------------+------+---------+-------+------+----------+-----------------+ 


EXPLAIN EXTENDED SELECT * FROM main_hash_db.main_tbl WHERE md5 = '...' UNION ALL SELECT * FROM main_hash_db.main_tbl WHERE sha1 = '...' UNION ALL SELECT * FROM main_hash_db.main_tbl WHERE sha256 = '...' 

+----+--------------+--------------+-------+-----------------------+---------+---------+-------+------+----------+-----------------+ 
| id | select_type | table  | type | possible_keys   | key  | key_len | ref | rows | filtered | Extra   | 
+----+--------------+--------------+-------+-----------------------+---------+---------+-------+------+----------+-----------------+ 
| 1 | PRIMARY  | main_tbl  | const | md5     | md5  | 97  | const | 1 | 100.00 | NULL   | 
| 2 | UNION  | main_tbl  | const | sha1,sha1_idx,md5_idx | sha1 | 121  | const | 1 | 100.00 | NULL   | 
| 3 | UNION  | main_tbl  | const | PRIMARY,sha256_idx | PRIMARY | 192  | const | 1 | 100.00 | NULL   | 
| NULL | UNION RESULT | <union1,2,3> | ALL | NULL     | NULL | NULL | NULL | NULL |  NULL | Using temporary | 
+----+--------------+--------------+-------+-----------------------+---------+---------+-------+------+----------+-----------------+ 

. 그러나 수정 후 가지 (초당 70 개 선택은 ~)는 여전히 느리고, 여기 EXPLAIN의 출력입니다 :

+----+--------------+--------------+-------+--------------------+---------+---------+-------+------+----------+-----------------+ 
| id | select_type | table  | type | possible_keys  | key  | key_len | ref | rows | filtered | Extra   | 
+----+--------------+--------------+-------+--------------------+---------+---------+-------+------+----------+-----------------+ 
| 1 | PRIMARY  | main_tbl  | const | md5,md5_idx  | md5  | 97  | const | 1 | 100.00 | NULL   | 
| 2 | UNION  | main_tbl  | const | sha1,sha1_idx  | sha1 | 121  | const | 1 | 100.00 | NULL   | 
| 3 | UNION  | main_tbl  | const | PRIMARY,sha256_idx | PRIMARY | 192  | const | 1 | 100.00 | NULL   | 
| NULL | UNION RESULT | <union1,2,3> | ALL | NULL    | NULL | NULL | NULL | NULL |  NULL | Using temporary | 
+----+--------------+--------------+-------+--------------------+---------+---------+-------+------+----------+-----------------+ 

는 ==================== ========================================================================================================== ========== 자세한 설명에 따라

세 번째 편집 (아래 참조). 여기에 원래의 질의에 대한 EXPLAIN 출력 (추가 인덱스가 정의되지는 전술 한 바와 같이, 데이터베이스가 생성)입니다 : 내 응용 프로그램에 의해 측정

explain extended select path from main_hash_db.main_tbl where sha256 = '...' or md5 = '...' or sha1 = '...' ; 

+----+-------------+----------+-------------+------------------+------------------+------------+------+------+----------+--------------------------------------------+ 
| id | select_type | table | type  | possible_keys | key    | key_len | ref | rows | filtered | Extra          | 
+----+-------------+----------+-------------+------------------+------------------+------------+------+------+----------+--------------------------------------------+ 
| 1 | SIMPLE  | main_tbl | index_merge | PRIMARY,sha1,md5 | PRIMARY,md5,sha1 | 192,97,121 | NULL | 3 | 100.00 | Using union(PRIMARY,md5,sha1); Using where | 
+----+-------------+----------+-------------+------------------+------------------+------------+------+------+----------+--------------------------------------------+ 

성능으로 :

Selects per second: 500.6 
Inserts per second: 1394.8 

이 3 개 선택과 결과 (하지 UNION와 별도로 발행) :

Selects per second: 2525.1 
Inserts per second: 1584.3 

답변

3

첫째, 당신이 빨리 될 인덱스없이 insert을 기대. 거기에는 수수께끼가 없습니다. 색인은 유지할 필요가 없습니다. 사실 큰 삽입 작업을 수행 할 때 인덱스를 먼저 삭제하고 삽입을 수행 한 다음 다시 작성하는 것이 좋습니다.

select는 더 문제가된다. 결국 인덱스가 사용되기를 원합니다.귀하의 검색어 :

SELECT * 
FROM hash_db.main_tbl 
WHERE sha256 = '...' OR 
     sha1 = '...' OR 
     md5 = '...'; 

이것은 인덱스 사용에있어서 최악의 경우입니다. 인덱스가 어떻게 사용되고 있는지 보려면 explain을 봐야합니다.

나의 추천은이 같은 쿼리 작성하는 것입니다 : (. 또는 당신이 정말로 중복을 제거하려는 경우 union 사용)

SELECT * 
FROM hash_db.main_tbl 
WHERE sha256 = '...' 
UNION ALL 
SELECT * 
FROM hash_db.main_tbl 
sha1 = '...' 
UNION ALL 
SELECT * 
FROM hash_db.main_tbl 
WHERE md5 = '...'; 

을이 각 하위 쿼리에 대한 각 인덱스의 장점을 가지고해야한다

원하는 성과를 제공하십시오.

+0

나는 당신의 제안을 시도했는데 실제로 많은 성능을 악화 시켰습니다. 이제 초당 70 건이 선택됩니다. 내 생각 엔 인덱스는 실제로 사용되지만 RAM 캐시 캐시 대신 많은 디스크 액세스가 발생하는 것입니다. 내가 뭘하고 있니? my.ini에서 일부 버퍼를 늘려야합니까? (어느 것입니까?) – user3671607

+0

더 나은 버퍼가 필요할 수도 있지만'explain' 계획을 살펴 보았습니다. –

+0

Gordon, 나는 원래 질문을'EXPLAIN' 결과로 편집했습니다. – user3671607

0

하면 성능이 저하하고 인덱스

마다의 다양한 수를 만들 수 있기 때문에 데이터베이스 흐름을 느리게 할 때 삽입의 당신이 당신의 시스템 SGBD에서 지수의 직접 수를 늘리는 것을 의미하는 하나의 튜플

당신이 선택을 할 때 조사와 같은 것입니다. 많은 수의 인덱스를 가지고 시스템에서 어떤 도전을합니다; 우선 순위와 같은 우선 순위를 가지며 3000 개의 인덱스를 가진 DB에서 1000 개의 튜플을 가질 수 있습니다.

모든 소프트웨어가 인덱스를 관리 할 수 ​​있습니다. 당신은 인덱스를 마스터하는 법을 알고 있어야합니다. 그러면 시스템을 최대의 가능성으로 밀어 낼 수 있습니다. 예를 들어 인덱스가있는 trrigrs를 사용하여 균형을 잘 잡을 수 있습니다.

관련 문제