MySQL, не используя индексы, с ГДЕ В пункте?

Я предполагаю, что вы хотите запросить непрочитанные сообщения для данного пользователя, поскольку (опять же) я предполагаю, что состояние чтения / непрочитанного данного уведомления не должно изменяться для одного пользователя, если другой пользователь читает уведомление для тоже самое.

Исходя из этого предположения, вы должны использовать разреженный индекс с userId (или эквивалентным) в качестве хеш-ключа и unreadNotificationTime в качестве ключа сортировки. Когда вы вставляете новое уведомление в вашу таблицу, установите значение unreadNotificationTime на отметку времени для уведомления. Когда пользователь прочитал уведомление, удалите атрибут unreadNotificationTime из элемента.

Почему это работает?

DynamoDB требует только, чтобы элемент имел ключевые атрибуты базовой таблицы, а любые другие атрибуты были необязательными. Работа индексов в DynamoDB заключается в том, что элемент из базовой таблицы будет отображаться только в индексе элемента, имеющего все ключевые атрибуты этого конкретного индекса.

При установке значения для unreadNotificationTime при сохранении уведомления все вновь созданные уведомления будут автоматически заполняться индексом непрочитанных сообщений. Удаляя unreadNotificationTime при прочтении сообщения, вы извлекаете уведомление из этого индекса. С этой схемой нет необходимости в каких-либо операциях фильтрации или сканирования. Ваш индекс будет содержать только непрочитанные уведомления, сгруппированные по идентификатору пользователя и отсортированные по дате.

49
задан Vladimir Vagaytsev 4 October 2018 в 01:41
поделиться

4 ответа

Попытайтесь вызвать этот индекс:

SELECT `user_metrics`.*
FROM `user_metrics` FORCE INDEX (index_user_metrics_on_user_id)
WHERE (`user_metrics`.user_id IN (N,N,N,N,N,N,N,N,N,N,N,N))

я просто проверил, это действительно использует индекс на точно том же запросе:

EXPLAIN EXTENDED
SELECT * FROM tests WHERE (test IN ('test 1', 'test 2', 'test 3', 'test 4', 'test 5', 'test 6', 'test 7', 'test 8', 'test 9'))

1, 'SIMPLE', 'tests', 'range', 'ix_test', 'ix_test', '602', '', 9, 100.00, 'Using where'
14
ответ дан Quassnoi 7 November 2019 в 11:50
поделиться

Посмотрите, что Индексы .

Использования MySQL How

Также проверяют, работает ли MySQL все еще полное сканирование таблицы после добавления дополнительных 2000-so строк к Вашему user_metrics таблица. В маленьких таблицах доступ индексом является на самом деле более дорогим (I/O-wise), чем сканирование таблицы, и оптимизатор MySQL мог бы принять это во внимание.

Вопреки моему предыдущему сообщению , оказывается, что MySQL также использование оптимизатора на основе издержек , который является очень хорошими новостями - то есть, если Вы выполняете Ваш ANALYZE, по крайней мере, однажды, когда Вы полагаете, что объем данных в Вашей базе данных представитель из будущего ежедневного использования.

При контакте с оптимизаторами на основе издержек (Oracle, Пост-ГРЭС, и т.д.), необходимо удостовериться, что периодически работали ANALYZE на различных таблицах, когда их размер увеличивается больше чем на 10-15%. (Пост-ГРЭС сделает это автоматически для Вас, по умолчанию, тогда как другой RDBMSs оставит эту ответственность перед DBA, т.е. Вами.) Через статистический анализ, ANALYZE поможет оптимизатору получить лучшее представление о том, сколько ввода-вывода (и другие связанные ресурсы, такие как ЦП, необходимый, например, для сортировки), будет включено при выборе между различными планами выполнения кандидата. Отказ работать ANALYZE может привести к очень плохому, иногда катастрофические решения планирования (например, взятие запросов миллисекунды, иногда, часы из-за [1 120] плохие вложенные циклы на JOIN с.)

, Если производительность будет все еще неудовлетворительной после выполнения ANALYZE, то Вы обычно будете в состоянии работать вокруг проблемы при помощи подсказок, например, FORCE INDEX, тогда как в других случаях Вы, возможно, споткнулись ошибку MySQL (например, этот более старый один , который, возможно, укусил Вас, были Вы для использования направляющих nested_set).

Теперь, , так как Вы находитесь в приложении для направляющих, это будет громоздким (и победит цель ActiveRecord) выпустить Ваши пользовательские запросы с подсказками вместо того, чтобы продолжить использовать ActiveRecord - сгенерированные.

я упомянул, что в нашем приложении направляющих весь SELECT запросы, опущенные ниже 100 мс после переключения на Пост-ГРЭС, тогда как некоторые сложные соединения, сгенерированные [1 112], будут иногда брать столько же сколько 15 или больше с MySQL 5.1 из-за вложенных циклов с внутренними сканированиями таблицы, даже когда индексы были доступны. Никакой оптимизатор не прекрасен, и необходимо знать об опциях. Другие потенциальные проблемы производительности для знания, помимо оптимизации плана запросов, блокируют. Это выходит за рамки Вашей проблемы все же.

45
ответ дан Tim Cooper 7 November 2019 в 11:50
поделиться

MySQL Sometimes не использует индекс, даже если Вы доступны. Одно обстоятельство, при котором это происходит, - когда оптимизатор оценивает, что использование индекса потребовало бы, чтобы MySQL получил доступ к очень большому проценту строк в таблице. (В этом случае сканирование таблицы, вероятно, будет намного быстрее, потому что оно требует, чтобы меньше искали.)

, Какой процент строк соответствует Вашему В пункте?

7
ответ дан mluebke 7 November 2019 в 11:50
поделиться

Это добирается немного лучше при удалении избыточных скобок вокруг где пункт?

, Хотя могло просто случиться так, что, потому что Вы только получили приблизительно 200 строк, это решило, сканирование таблицы будет быстрее. Попробуйте таблицей с большим количеством записей в нем.

0
ответ дан Paul Tomblin 7 November 2019 в 11:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: