Это моя модель базы данных:Как заставить базу данных MySQL игнорировать оптимизацию?
В моей базе данных, таблица документ содержит 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;
Поместите SQL_NO_CACHE в ваши инструкции SELECT при тестировании запросов. например 'SELECT SQL_NO_CACHE term.term из term order by rand() limit 1'. Повторите свои тесты и обновите свой вопрос с результатами, которые вы получите, пожалуйста. –
Можете ли вы поделиться «DESC» по запросу? Мы можем потенциально заставить индекс. –
SQL_NO_CACHE действительно помог, спасибо большое –