Индекс не используется в зависимости от привязки параметра и кодировкиPhp

Кемеровские программисты php общаются здесь
Ответить
Anonymous
 Индекс не используется в зависимости от привязки параметра и кодировки

Сообщение Anonymous »

Вопрос
Почему мой индекс игнорируется при определенных обстоятельствах, что приводит к замедлению выполнения. Я нашел причину в сочетании использования UNION ALL + выбранного API базы данных PHP + выбранной кодировки + использованной реализации привязки параметров.
Настройка
Я создал представление my_view, которое выглядит следующим образом:

Код: Выделить всё

SELECT type FROM table1

UNION ALL

SELECT type FROM table2
Обе таблицы: table1 и 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);

Теперь я хочу выбрать все записи, где тип = 1. Это должно быть довольно просто:

Код: Выделить всё

SELECT * FROM my_view WHERE type = 1;
Выполнение EXPLAIN для этого запроса дает следующий результат:

Код: Выделить всё

┌────┬─────────────┬────────────┬───────┬───────────────┬────────┬─────────┬────────┬──────┬─────────────┐
│ 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 │
└────┴─────────────┴────────────┴───────┴───────────────┴────────┴─────────┴────────┴──────┴─────────────┘
Выполнение операторов SELECT в консоли SQL работает отлично и очень быстро.
Проблема
Это меняется, когда я использую 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 (по умолчанию)

Код: Выделить всё

->execute_query($sql, [$type])

❌
mysqli (по умолчанию)

Код: Выделить всё

->prepare(); ->bind_param()
; ->execute(); ->get_result()


❌
mysqli

Код: Выделить всё

->set_charset('utf8mb4')

Код: Выделить всё

->execute_query($sql, [$type])

❌
mysqli

Код: Выделить всё

->set_charset('utf8mb4')

Код: Выделить всё

->prepare(); ->bind_param()
; ->execute(); ->get_result()


✅
PDO (по умолчанию)

Код: Выделить всё

ATTR_EMULATE_PREPARES = true
(по умолчанию)


✅
PDO (по умолчанию)

Код: Выделить всё

->setAttribute(PDO::ATTR_EMULATE_PREPARES, false)

✅
PDO

Код: Выделить всё

new PDO("...charset=utf8mb4", ...)

Код: Выделить всё

ATTR_EMULATE_PREPARES = true
(по умолчанию)


❌
PDO

Код: Выделить всё

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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Php»