Получение общего количества записей из таблицы MySQL - слишком медленно - PullRequest
0 голосов
/ 27 июля 2010

У меня есть файл, который проходит через большой набор данных и разбивает строки на страницы.Набор данных содержит около 210 тыс. Строк, что не так уж много, за несколько недель он вырастет до 3Mil +, но он уже медленный.

У меня есть первый запрос, который получает общее количество элементов вБД для конкретной комбинации предложений WHERE, самая основная из которых выглядит следующим образом:

SELECT count(v_id) as num_items FROM versions 
WHERE v_status = 1

Требуется 0,9 секунды для запуска.

Второй запрос - это запрос LIMIT, который получает фактические данныедля этой страницы.Этот запрос действительно быстрый.(менее 0,001 с).

SELECT 
        v_id, 
        v_title,
        v_desc
    FROM versions 
    WHERE v_status = 1 
    ORDER BY  v_dateadded DESC 
    LIMIT 0, 25

Есть индекс v_status, v_dateadded

Я использую php.Я кеширую результат в memcace, поэтому последующие запросы выполняются очень быстро, но первый запрос запаздывает.Особенно, когда я добавляю полнотекстовый поиск, на 2 запроса уходит 2-3 секунды.

Ответы [ 4 ]

2 голосов
/ 27 июля 2010

Я не думаю, что это правильно, но попробуйте сделать это считать (*), я думаю, что count (x) должен пройти через каждую строку и считать только те, которые не имеют нулевого значения (поэтомудолжен пройти через все строки)

Учитывая, что v_id является ПЕРВИЧНЫМ КЛЮЧОМ, в нем не должно быть нулей, поэтому вместо этого попробуйте count (*) ...

Но я не думаю, чтоэто поможет, так как у вас есть предложение where.

0 голосов
/ 17 января 2014

РЕДАКТИРОВАТЬ: Для меня FOUND_ROWS () был самый быстрый способ сделать это:

SELECT 
        SQL_CALC_FOUND_ROWS
        v_id, 
        v_title,
        v_desc
    FROM versions 
    WHERE v_status = 1 
    ORDER BY  v_dateadded DESC 
    LIMIT 0, 25;

Тогда во вторичном запросе просто выполните:

SELECT FOUND_ROWS();

Если вы выводите на PHPвы делаете это:

$totalnumber = mysql_result(mysql_query($secondquery)),0,0);

Ранее я пытался сделать то же самое, что и OP, поместив COUNT (column) в первый запрос, но это заняло примерно в три раза больше времени, чем даже самый медленный запрос WHERE и ORDERBYчто я мог сделать (с набором LIMIT).Я попытался изменить на COUNT (*), и он значительно улучшился.Но результаты в моем случае были даже лучше, если использовать MySQL FOUND_ROWS ();

Я тестирую на PHP с microtime и повторяю запрос.В случае OP, если он запускает COUNT (*), я думаю, что он сэкономит некоторое время, но это не самый быстрый способ сделать это.Я провел несколько тестов на COUNT (*) VS.FOUND_ROWS () и FOUND_ROWS () работают немного быстрее.

Использование FOUND_ROWS () в моем случае было почти в два раза быстрее.

Сначала я начал выполнять EXPLAIN для запроса COUNT (*),В случае OP вы увидите, что MySQL по-прежнему проверяет в общей сложности 210 тыс. Строк в первом запросе.Он проверяет каждую строку перед тем, как даже запускать запрос LIMIT, и, похоже, от этого не выигрывает производительность.

Если вы запустите EXPLAIN для запроса LIMIT, он, вероятно, проверит менее 100 строк, поскольку вы ограничили результаты до 25. Но это все еще перекрытие, и в некоторых случаях вы не можете себе этого позволить илипо крайней мере, вы все равно должны сравнивать производительность с FOUND_ROWS ().

Я думал, что это могло бы сэкономить время только на больших запросах LIMIT, но когда я запускал EXPLAIN для моего запроса LIMIT, он фактически проверял только 25 строк, чтобы получить 15ценности.Тем не менее, разница во времени запроса все еще была очень заметной - в среднем я снизился с 0,25 до 0,14 секунды и достиг тех же результатов.

0 голосов
/ 27 июля 2010

Запустите план объяснения, чтобы увидеть, как оптимизатор выполняет ваши запросы.

Это, вероятно, скажет вам то, что сказал вам Андреас Рем: вы захотите добавить индексы, которые охватывают ваши предложения where.*

0 голосов
/ 27 июля 2010

Не уверен, что это одинаково для MySQL, но в MS SQL Server COUNT (*) почти всегда быстрее, чем COUNT (столбец). Парсер определяет самый быстрый столбец для подсчета и использует его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...