Почему мой индекс игнорируется при определенных обстоятельствах, что приводит к замедлению выполнения. Я нашел причину в сочетании использования UNION ALL + выбранного API базы данных PHP + выбранной кодировки + использованной реализации привязки параметров.
Настройка
Я создал представление my_view, которое выглядит следующим образом:
Код: Выделить всё
SELECT type FROM table1
UNION ALL
SELECT type FROM table2
Код: Выделить всё
CREATE TABLE table1
(
id INT UNSIGNED AUTO_INCREMENT,
type INT NOT NULL,
... -- some more data columns
PRIMARY KEY (id)
);
CREATE INDEX my_idx ON table1 (type);
Код: Выделить всё
SELECT * FROM my_view WHERE type = 1;
Код: Выделить всё
┌────┬─────────────┬────────────┬───────┬───────────────┬────────┬─────────┬────────┬──────┬─────────────┐
│ id │ select_type │ table │ type │ possible_keys │ key │ key_len │ ref │ rows │ Extra │
╞════╪═════════════╪════════════╪═══════╪═══════════════╪════════╪═════════╪════════╪══════╪═════════════╡
│ 1 │ PRIMARY │ │ ALL │ │ │ │ │ 110 │ Using where │
│ 2 │ DERIVED │ table1 │ const │ my_idx │ my_idx │ 5 │ const │ 72 │ Using index │
│ 3 │ UNION │ table2 │ const │ my_idx │ my_idx │ 5 │ const │ 38 │ Using index │
└────┴─────────────┴────────────┴───────┴───────────────┴────────┴─────────┴────────┴──────┴─────────────┘
Проблема
Это меняется, когда я использую PHP для выполнения запроса. В зависимости от API подключения к базе данных (например, mysqli, PDO) моя база данных решает не использовать индекс для моего представления, используя тот же запрос, что и раньше:
Код: Выделить всё
┌────┬─────────────┬────────────┬───────┬───────────────┬────────┬─────────┬─────┬──────────┬─────────────┐
│ id │ select_type │ table │ type │ possible_keys │ key │ key_len │ ref │ rows │ Extra │
╞════╪═════════════╪════════════╪═══════╪═══════════════╪════════╪═════════╪═════╪══════════╪═════════════╡
│ 1 │ PRIMARY │ │ ALL │ │ │ │ │ 56247595 │ Using where │
│ 2 │ DERIVED │ table1 │ index │ │ my_idx │ 5 │ │ 34706361 │ Using index │
│ 3 │ UNION │ table2 │ index │ │ my_idx │ 5 │ │ 21541234 │ Using index │
└────┴─────────────┴────────────┴───────┴───────────────┴────────┴─────────┴─────┴──────────┴─────────────┘
Моя отладка показала, что следующие комбинации используют индекс (
API
кодировка
дополнительно (методы/опции)
mysqli
Код: Выделить всё
latin1Код: Выделить всё
->execute_query($sql, [$type])mysqli
Код: Выделить всё
latin1Код: Выделить всё
->prepare(); ->bind_param()mysqli
Код: Выделить всё
->set_charset('utf8mb4')Код: Выделить всё
->execute_query($sql, [$type])mysqli
Код: Выделить всё
->set_charset('utf8mb4')Код: Выделить всё
->prepare(); ->bind_param()PDO
Код: Выделить всё
latin1Код: Выделить всё
ATTR_EMULATE_PREPARES = truePDO
Код: Выделить всё
latin1Код: Выделить всё
->setAttribute(PDO::ATTR_EMULATE_PREPARES, false)PDO
Код: Выделить всё
new PDO("...charset=utf8mb4", ...)Код: Выделить всё
ATTR_EMULATE_PREPARES = truePDO
Код: Выделить всё
new PDO("...charset=utf8mb4", ...)Код: Выделить всё
->setAttribute(PDO::ATTR_EMULATE_PREPARES, false)Я не могу понять смысла этого. Что здесь происходит?
Информация о версии
- MariaDB 10.6.18
< li>PHP 8.2.26
Подробнее здесь: https://stackoverflow.com/questions/792 ... ng-charset
Мобильная версия