Мне показалось, что у меня почти что работоспособное понимание баз данных, но это предположение только что было выброшено из окна.
У меня довольно большая таблица, и я выполняю простой запрос по ней:
select image_set_id from image where table_id = 554;
image_set_id - это длинный внешний ключ к другой таблице. Для выполнения этого запроса на моем компьютере может потребоваться более 7 секунд (на сервере базы данных, который не имеет такой большой мощности ...)
Однако, если я выполню этот запрос:
select id from image where table_id = 554;
это почти в сто раз быстрее. Очевидным отличием является то, что id является первичным ключом, а также LONG.
Что удивительно, так это то, что оба запроса сравниваются с внешним ключом в предложении where, поэтому я ожидал, что оба запроса будут занимать примерно одинаковое время. Я имею в виду, что БД должна отфильтровывать все записи, соответствующие внешнему ключу, затем читать LONG из каждой из них, и все. Характер читаемого значения не должен иметь такого же значения, как характер сравниваемого значения. Если я выполню объяснение по двум запросам, результат даже будет выглядеть точно так же:

Ну, очевидно, я совершенно не прав, поэтому у меня есть два вопросы:
а) Почему это так?
б) Можно ли как-нибудь улучшить производительность при выборе внешнего ключа, потому что в конце концов это то, что мне нужно (это подзапрос более крупного запроса, который нуждается в оптимизации, но потребляет более 90% времени выполнения)?
Дополнительные данные:
Структура, используемая здесь, относительно проста. Здесь задействованы три таблицы: одна раздраженно называется image_table, одна называется image_set и одна называется image. Каждое изображение принадлежит определенной image_table. Image_set - это отношение, которое описывает изображения из разных image_tables, которые принадлежат друг другу (это фактически несколько версий одного и того же изображения). Таким образом, изображение имеет внешний ключ как для image_table, так и для image_set, в то время как между image_set и image_table нет никакой связи.
Вот полная структура задействованных таблиц:
explain image;
'id', 'binary(16)', 'NO', 'PRI', NULL, ''
'image_key', 'varchar(190)', 'YES', 'UNI', NULL, ''
'image_preview_key', 'varchar(255)', 'NO', '', NULL, ''
'image_set_id', 'bigint(20)', 'NO', 'MUL', NULL, ''
'table_id', 'bigint(20)', 'YES', 'MUL', NULL, ''
'size', 'int(11)', 'NO', '', '0', ''
SHOW INDEX FROM image;
'image', '0', 'PRIMARY', '1', 'id', 'A', '20201850', NULL, NULL, '', 'BTREE', '', ''
'image', '0', 'UX_image_image_key', '1', 'image_key', 'A', '20201850', NULL, NULL, 'YES', 'BTREE', '', ''
'image', '1', 'FK_image_image_set', '1', 'image_set_id', 'A', '20201850', NULL, NULL, '', 'BTREE', '', ''
'image', '1', 'FK_image_image_table', '1', 'table_id', 'A', '75099', NULL, NULL, 'YES', 'BTREE', '', ''
explain image_set;
'id', 'bigint(20)', 'NO', 'PRI', NULL, 'auto_increment'
'time', 'datetime', 'NO', 'MUL', NULL, ''
'camera_id', 'bigint(20)', 'YES', 'MUL', NULL, ''
SHOW INDEX FROM image_set;
'image_set', '0', 'PRIMARY', '1', 'id', 'A', '8317139', NULL, NULL, '', 'BTREE', '', ''
'image_set', '0', 'UX_image_set_time', '1', 'camera_id', 'A', '29080', NULL, NULL, 'YES', 'BTREE', '', ''
'image_set', '0', 'UX_image_set_time', '2', 'time', 'A', '8317139', NULL, NULL, '', 'BTREE', '', ''
'image_set', '1', 'IX_image_set_time', '1', 'time', 'A', '8317139', NULL, NULL, '', 'BTREE', '', ''
explain image_table;
'id', 'bigint(20)', 'NO', 'PRI', NULL, 'auto_increment'
'name', 'varchar(255)', 'NO', '', NULL, ''
'legacy_name', 'varchar(100)', 'NO', 'UNI', NULL, ''
'camera_id', 'bigint(20)', 'NO', 'MUL', NULL, ''
'instruction_id', 'bigint(20)', 'YES', 'MUL', NULL, ''
'trashed', 'datetime', 'YES', '', NULL, ''
SHOW INDEX FROM image_table;
'image_table', '0', 'PRIMARY', '1', 'id', 'A', '1128', NULL, NULL, '', 'BTREE', '', ''
'image_table', '0', 'legacy_name', '1', 'legacy_name', 'A', '1128', NULL, NULL, '', 'BTREE', '', ''
'image_table', '1', 'FK_image_table_camera', '1', 'camera_id', 'A', '1128', NULL, NULL, '', 'BTREE', '', ''
'image_table', '1', 'FK_image_table_image_table_instruction', '1', 'instruction_id', 'A', '1128', NULL, NULL, 'YES', 'BTREE', '', ''
При описании двух рассматриваемых запросов они выглядят почти одинаково, за исключением того, что один использует индекс, а другой нет ... хотя индекс для него существует:
describe select image_set_id from image where table_id = 554;
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "image",
"access_type": "ref",
"possible_keys": [
"FK_image_image_table"
],
"key": "FK_image_image_table",
"used_key_parts": [
"table_id"
],
"key_length": "9",
"ref": [
"const"
],
"rows": 698122,
"filtered": 100
}
}
}
describe select id from image where table_id = 554;
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "image",
"access_type": "ref",
"possible_keys": [
"FK_image_image_table"
],
"key": "FK_image_image_table",
"used_key_parts": [
"table_id"
],
"key_length": "9",
"ref": [
"const"
],
"rows": 698122,
"filtered": 100,
"using_index": true
}
}
}