2013-04-08 4 views
0

У меня есть две таблицы: maskedindextable и dictionarytable.Как оптимизировать следующий запрос?

dictionarytable имеет четыре колонки:

ID (primary key) 
filelocation 
dictionaryEncryptedIndex 
dictionaryEncryptedWord 

и значения выглядят следующим образом:

ID | filelocation | dictionaryencryptedindex | dictionaryEncryptedWord 
0 | c:/test.txt | 0x01 | EAD64zef6z 
1 | c:/test.txt | 0x02 | 5ez4f 
2 | c:/test.txt | 0x03 | ze654f 
3 | c:/john.txt | 0x01 | 6ze5f4 
4 | c:/john.txt | 0x02 | ze5f68z4f 
5 | c:/john.txt | 0x03 | EAD64zef6z 
6 | c:/smith.txt | 0x01 | er6g4 
7 | c:/smith.txt | 0x02 | z6e58g4 
8 | c:/smith.txt | 0x03 | a64zef6z 
9 | c:/laura.txt | 0x01 | EAD64zef6z 

Эта таблица содержит 700 000 значений

maskedindextable имеет четыре колонки:

ID (primary key) 
filelocation 
maskedIndexEncryptedIndex 
maskedIndexEncryptedValue 

значения выглядеть следующим образом:

ID | filelocation | maskedIndexEncryptedIndex | maskedIndexEncryptedValue 
0 | c:/test.txt | 0x01 | 5z1ef 
1 | c:/test.txt | 0x02 | e6rh546er4g 
2 | c:/test.txt | 0x03 | z6ef548ezf 
3 | c:/john.txt | 0x01 | (y48try68 
4 | c:/john.txt | 0x02 | iu47k 
5 | c:/john.txt | 0x03 | 6tkj 
6 | c:/smith.txt | 0x01 | 6ez5r48 
7 | c:/smith.txt | 0x02 | 6i5 
8 | c:/smith.txt | 0x03 | 6e5rg 
9 | c:/laura.txt | 0x01 | ze654f 

В этой таблице также имеет 700 000 значений

dictionaryencryptedindex & filelocation сочетание в таблице dictionarytable соответствует maskedIndexEncryptedIndex & filelocation в таблице maskedindextable. Я хочу найти соответствующее значение maskedindexencryptedvalue, для которого зашифрованными словами являются EAD64zef6z. В настоящее время я использую следующий запрос:

SELECT DISTINCT MaskedIndexTable.filelocation, 
     dictionaryencryptedindex, 
     maskedindexencryptedvalue 
FROM MaskedIndexTable 
INNER JOIN DictionaryTable 
     ON MaskedIndexTable.maskedIndexEncryptedIndex = 
      DictionaryTable.dictionaryEncryptedIndex 
WHERE MaskedIndexTable.Id IN 
(SELECT DictionaryTable.Id 
FROM DictionaryTable 
WHERE `dictionaryEncryptedWord` LIKE 'EAD64zef6z') 
AND `dictionaryEncryptedWord` LIKE 'EAD64zef6z'; 

Но этот запрос работает очень медленно (занимает 3 секунды). Кто-нибудь знает, как я могу оптимизировать свой запрос?

+1

индексирование, в соответствии с ответом Марджеты является наилучшим выбором. Кроме того, в каждом небольшом вспомогательном отделе вы используете LIKE без шаблона. Использование = может дать вам наносекунду или два. –

+0

Большинство двигателей баз данных обеспечивают способ проверки плана запроса, чтобы определить, какая часть запроса вызывает проблемы с производительностью (например, отсутствующие индексы). Хотя в этом случае я подозреваю, что это ваш суб-выбор, а не отсутствующий индекс. – RickF

ответ

2

Как о простом заявлении

SELECT dt.filelocation, dictionaryencryptedindex, maskedindexencryptedvalue 
FROM MaskedIndexTable mit 
INNER JOIN DictionaryTable dt 
    ON mit.maskedIndexEncryptedIndex = dt.dictionaryEncryptedIndex 
    AND mit.filelocation = dt.filelocation 
WHERE dt.dictionaryEncryptedWord = 'EAD64zef6z'; 

Вам не нужно LIKE, если вы не используете специальные символы. Также вы можете добавить несколько условий в пункт ON инструкции JOIN.

Вам понадобятся индексы на WHERE и столбцам, т.е. DictionaryTable.dictionaryEncryptedWord, DictionaryTable.filelocation, DictionaryTable.dictionaryEncryptedIndex, MaskedIndexTable.filelocation и MaskedIndexTable.maskedIndexEncryptedIndex

+0

Большое спасибо за вашу помощь, это прекрасно работает и является огромным улучшением. – user2241821

1

По моему опыту, когда запрос выполняется медленно, оказывается, что столбец, упомянутый в предложении WHERE, не имеет индекса.

Попробуйте индексировать все столбцы, появляющиеся в предложениях WHERE.

+0

Если вам нужна помощь в создании INDEXES, вы можете начать здесь: http://www.w3schools.com/sql/sql_create_index.asp –

0

попытаться удалить выберите в где clausure

SELECT DISTINCT MaskedIndexTable.filelocation, dictionaryencryptedindex 
,  maskedindexencryptedvalue 

FROM MaskedIndexTable INNER JOIN DictionaryTable ON MaskedIndexTable.maskedIndexEncryptedIndex = DictionaryTable.dictionaryEncryptedIndex 
WHERE `dictionaryEncryptedWord` LIKE 'EAD64zef6z'; 
1

На первый взгляд, суб-выделить в ИНЕКЕ, кажется, не служат никакой цели. Вы также используете LIKE вместо простого =. Попробуйте следующее:

SELECT DISTINCT MIT.filelocation, 
    dictionaryencryptedindex, 
    maskedindexencryptedvalue 
FROM MaskedIndexTable MIT 
    INNER JOIN DictionaryTable DT 
    ON MIT.maskedIndexEncryptedIndex = 
     DT.dictionaryEncryptedIndex 
WHERE dictionaryEncryptedWord = 'EAD64zef6z'; 
Смежные вопросы