sql — производительность подсчета mysql

выберите количество (*) из mytable;
выберите количество (table_id) из mytable; // table_id является первичным_ключем

оба запроса выполнялись медленно в таблице с 10 миллионами строк.
Я задаюсь вопросом, почему так как MySQL не может легко сохранить счетчик, который обновляется на всех вставках, обновлениях и удалениях?
и есть ли способ улучшить этот запрос? Я использовал объяснить, но не сильно помог.

4

Решение

Как отметил в комментариях черувим, это зависит от механизма хранения.

MyISAM сохраняет количество строк таблицы и может поддерживать его точность, поскольку единственная блокировка, поддерживаемая MyISAM, — это блокировка таблицы.

InnoDB однако поддерживает транзакции и должен выполнить сканирование таблицы для подсчета строк.

http://www.mysqlperformanceblog.com/2006/12/01/count-for-innodb-tables/

4

Другие решения

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

1) COUNT (***) против COUNT (кол)
2) Easy MySQL Performance Tips
3) Быстрый подсчет (*) для InnoDB

Кстати, какой двигатель вы используете?

Редакция: О технике для ускорения подсчета, когда вам нужно просто знать, есть ли количество строк. Извините, просто не так с моим запросом. Итак, когда вам нужно просто знать, есть ли, например, 300 строк по конкретным условиям вы можете попробовать подзапрос:

select count(*) FROM
( select 1 FROM _table_ WHERE _conditions_ LIMIT 300 ) AS result

сначала вы минимизируете набор результатов, а затем подсчитываете результат; он все равно будет сканировать набор результатов, но вы можете ограничить его (еще раз, он работает, когда вопрос к БД «здесь больше или меньше 300 строк), и если БД содержит более 300 строк, которые удовлетворяют условию, что запрос выполняется быстрее

Результаты тестирования (в моей таблице 6,7 млн ​​строк):

1) SELECT count(*) FROM _table_ WHERE START_DATE > '2011-02-01'
возвращается 4,2 млн за 65,4 секунды

2) SELECT count(*) FROM ( select 1 FROM _table_ WHERE START_DATE > '2011-02-01' LIMIT 100 ) AS result
возвращается 100 за 0,03 секунды

Ниже приведен результат запроса объяснения, чтобы увидеть, что там происходит:

EXPLAIN SELECT count(*) FROM ( select 1 FROM _table_ WHERE START_DATE > '2011-02-01' LIMIT 100 ) AS result

введите описание изображения здесь

7