2015-04-27 2 views
1

Это моя модель базы данных:Как заставить базу данных MySQL игнорировать оптимизацию?

enter image description here

В моей базе данных, таблица документ содержит 1000 строк, таблица document_has_term имеет 700 000 строк и термин таблица содержит 1070 строк.

Это простой запрос, объединить все таблицы вместе и выбрать все идентификаторы из документа:

select 
    document.iddocument 
from 
    document 
join 
    document_has_term on document.iddocument = document_has_term.document_iddocument 
join 
    term on term.idterm = document_has_term.term_idterm 

Она занимает около 350 мс выполнить этот запрос. Если я это правильно понимаю, он повторяет все 700 000 индексов.

Перед выполнением следующего запроса я сброшу кеш и удостоверяюсь, что нет индекса на term.term столбец.

Затем я выполняю этот запрос, который аналогичен приведенному выше, только добавленному здесь. Термин, используемый для поиска, был случайным образом выбран из базы данных.

select document.iddocument from document join document_has_term on 
document.iddocument=document_has_term.document_iddocument 
join term on term.idterm=document_has_term.term_idterm where term.term=apple 

Теперь по некоторым причинам, выполнение этого запроса требуется только 3ms, что примерно в 100 раз быстрее, чем предыдущий запрос, и я не знаю, почему. Как я понимаю, когда нет индекса, установленного на retm.term, он должен перебрать все 700 000, чтобы дать мне результат, который займет как минимум столько же раз, сколько и раньше.

Так что мне интересно, как я могу заставить его искать линейный по всему индексу базы данных. Я очистил и сбросил кеш и сбросил каждый индекс с term.term, даже сбросив базу данных много раз, ничего не помогло.

Это пример кода, где я проверяю время выполнения запросов:

$servername = "localhost"; 
$username = "root"; 
$password = ""; 
$dbname = "myDB"; 

$conn = new mysqli($servername, $username, $password, $dbname); 
if ($conn->connect_error) { 
    die("Connection failed: " . $conn->connect_error); 
} 
$sql = "FLUSH QUERY CACHE"; 
$result = $conn->query($sql); 

$sql = "RESET QUERY CACHE"; 
$result = $conn->query($sql); 

$randomTerms = array(); 
$totalTime=0; 

for ($i = 0; $i < 100; $i++){ 
    global $conn, $randomTerms; 
    $sql = "select term.term from term order by rand() limit 1"; 
    $result = $conn->query($sql); 
    $row = $result->fetch_assoc(); 
    $randomTerms[] = $row["term"]; 
    echo $row["term"]."<br>"; 
} 

foreach ($randomTerms as $t){ 
    global $totalTime; 
    $sql = "select document.iddocument from document join document_has_term on document.iddocument=document_has_term.document_iddocument " 
      . "join term on term.idterm=document_has_term.term_idterm where term.term=\"$t\" "; 
    $algTime = microtime(true); 
    $result = $conn->query($sql); 
    $algTime = microtime(true) - $algTime; 
    $totalTime+=$algTime; 
} 

$averageTime = $totalTime/100; 
+1

Поместите SQL_NO_CACHE в ваши инструкции SELECT при тестировании запросов. например 'SELECT SQL_NO_CACHE term.term из term order by rand() limit 1'. Повторите свои тесты и обновите свой вопрос с результатами, которые вы получите, пожалуйста. –

+0

Можете ли вы поделиться «DESC» по запросу? Мы можем потенциально заставить индекс. –

+0

SQL_NO_CACHE действительно помог, спасибо большое –

ответ

0
SELECT SQL_NO_CACHE 

Добавление это запрос решить мою проблему.

+0

Сколько времени потребуется на выполнение запросов с 'SQL_NO_CACHE'? – axiac

+0

Около 230 мс, что меньше, чем итерация через строки 700 тыс., Но это хорошее измеримое значение, с которым я могу работать. Когда я применяю индекс, тогда я беру около 12 мс. –

Смежные вопросы