Причина в том, что идентификатор или строгий оператор (===), он сравнивается без преобразования типа, это означает, что если оба значения не имеют одинакового значения и одного и того же типа, они не будут считаться равными.
взгляните на эту ссылку, вы не можете сомневаться , чтобы понять, как работает оператор-идентификатор
Кластеризируемые первичные ключи использования InnoDB, таким образом, первичный ключ хранится наряду со строкой в страницах данных, не в отдельных индексных страницах. Чтобы сделать, диапазон сканирует Вас, все еще должны просканировать через все потенциально широкие строки в страницах данных; обратите внимание, что эта таблица содержит Столбец текста.
Две вещи я попробовал бы:
optimize table
. Это гарантирует, что страницы данных физически хранятся в отсортированном порядке. Это могло очевидно ускорить сканирование диапазона на кластеризованном первичном ключе. (Вы также, вероятно, хотите сделать change_event_id столбец bigint неподписанным , если он увеличивает от нуля)
Выполненный" analyze table_name
" на той таблице - возможно, что индексы больше не оптимальны.
можно часто говорить это путем выполнения" show index from table_name
". Если значение кардинальности NULL
затем, необходимо вызвать переанализ.
Вот несколько вещей, которые я предлагаю:
Изменение столбец от "bigint" до "неподписанного интервала". Вы действительно когда-либо ожидаете иметь больше чем 4,2 миллиарда записей в этой таблице? В противном случае затем Вы тратите впустую пространство (и время) общедополнительное поле. Индексы MySQL более эффективны на меньших типах данных.
Выполнение" ОПТИМИЗИРУЕТ ТАБЛИЦУ " команда и видит, является ли Ваш запрос немного быстрее позже.
Вы могли бы также рассмотреть разделение Вашей таблицы согласно полю ID, особенно если более старые записи (с более низкими Значениями идентификаторов) становятся менее релевантными со временем. Разделенная таблица может часто выполнять агрегатные запросы быстрее, чем одна огромная, неразделенная таблица.
РЕДАКТИРОВАНИЕ:
Рассмотрение более тесно этой таблицы, похоже на таблицу стиля входа, где строки вставляются, но никогда не изменяются.
, Если это правда, то Вам, возможно, не понадобилась бы вся транзакционная безопасность, обеспеченная механизмом устройства хранения данных InnoDB, и Вы смогли сходить с рук переключение на MyISAM, который значительно более эффективен на агрегатных запросах.
Я столкнулся с поведением как это прежде с базами данных геолокации IP. Прошлый некоторое количество записей, способность MySQL получить любое преимущество от индексов для основанных на диапазоне запросов, по-видимому, испаряется. С геолокацией DBS мы обработали его путем сегментации данных на блоки, которые были достаточно разумны позволить индексам использоваться.
Проверьте, чтобы видеть, насколько фрагментированный Ваши индексы. В моей компании у нас есть ночной процесс импорта, который повреждает наши индексы, и со временем она может оказать глубокое влияние на скорости доступа к данным. Например, у нас была процедура SQL, которая заняла 2 часа для выполнения спустя один день за дефрагментацией индексов, потребовалось 3 минуты. мы используем SQL Server, 2005 плохо ищет сценарий, который может проверить это на MySQL.
Обновление: Проверьте эту ссылку: http://dev.mysql.com/doc/refman/5.0/en/innodb-file-defragmenting.html
Я составил бы таблицу "счетчиков" и добавил бы, "создают строку" / "удаляют строку" триггеры к таблице, которую Вы считаете. Триггеры должны увеличиться/уменьшить значения количества на таблице "счетчиков" на каждом вставляемые/удалять, таким образом, Вы не должны будете вычислять их каждый раз, когда Вам нужны они.
можно также выполнить это на стороне приложения путем кэширования счетчиков, но это включит очистку "встречного кэша" на каждой вставке/удалении.
Для некоторой ссылки смотрят на этот http://pure.rednoize.com/2007/04/03/mysql-performance-use-counter-tables/
MySQL сначала говорит «Использование where», поскольку для их фактического подсчета необходимо прочитать все записи / значения из данных индекса. С InnoDb он также пытается «захватить» этот диапазон записей размером 4 мил для его подсчета.
Возможно, вам придется поэкспериментировать с различными уровнями изоляции транзакций: http://dev.mysql.com/doc/refman/5.1 /en/set-transaction.html#isolevel_read-uncommitted
и посмотрите, какой из них лучше.
С MyISAM это будет просто быстро, но при интенсивной модели записи возникнут проблемы с блокировкой.