Как две, казалось бы, идентичные базы данных возвращают результаты, отсортированные по разным столбцам? - PullRequest
0 голосов
/ 29 ноября 2018

У меня один запрос

SELECT r.id
     , r.account_id
     , r.name
     , r.bucket_id
     , r.description
     , r.development
     , r.created_at
     , r.priority
  FROM realms r
 WHERE r.account_id = 3;

Я запускаю его для двух разных таблиц с одинаковыми индексами, и один результат сортируется по r.id и r.created_at (в любом случае в одном и том же порядке), а другой отсортирован по r.name.Как это может быть?

Глядя на это через инспектор таблиц в MySQL Workbench, индексы для обоих:

+---------------------------+-------+-----+-----------------+
| key                       |Type   |Uni  | Columns         |
+ --------------------------+-------+-----+-----------------+
| PRIMARY                   | BTREE | YES | id              |
| realms_account_id_name_UQ | BTREE | YES | account_id,name |
| realms_account_id_IX      | BTREE | NO  | account_id      |
| realms_bucket_id_IX       | BTREE | NO  | bucket_id       |
+---------------------------+-------+-----+-----------------+

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

1 Ответ

0 голосов
/ 29 ноября 2018

Если в вашем SELECT нет предложения ORDER BY, система может делать все, что угодно.Период.Полная остановка.

Теперь я объясню, что произошло , вероятно .

Сначала оптимизатор проанализирует индексы, типы данных, статистику и т. Д. И решит, каквыполнить запрос.Вы можете взглянуть на эту операцию, выполнив EXPLAIN SELECT ....Он скажет, какой индекс он может использовать.

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

Анализ использования INDEX(account_id, name).Этот индекс представляет собой упорядоченный список пар account_ids и имен.На машине, где он использовал этот индекс, он детализировал индекс BTree до первой записи для account_id = 3, затем сканировал вперед.Это дало вам результаты, упорядоченные по name.

Анализ использования INDEX(account_id).InnoDB, чтобы найти данные, прикрепляет столбцы PRIMARY KEY к каждому вторичному индексу.Таким образом, этот индекс фактически равен INDEX(account_id, id).На машине, где он использовал этот индекс, он детализировал индекс BTree до первой записи для account_id = 3, затем сканировал вперед.Это дало вам результаты, упорядоченные по id.

Третья возможность распространена и стоит отметить.Если строк с account_id = 3 много, оптимизатор решит отказаться от индекса и просто прочитать данные.Поскольку данные хранятся в соответствии с PRIMARY KEY, они снова доставят строки в порядке id (но по совершенно другой причине).

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