subquery-opt-test – набор скриптов для эксперимента по оптимизации выявлению наиболее быстрого способа получения данных (запрос с подзапросом) из БД (mysql 8.0, innodb), или просто для опыта :)
Вкратце: надо выяснить, является ли SQL запрос ниже самым быстрым по времени выполнения:
SELECT * FROM t1 WHERE id IN(SELECT `t1` FROM `t2` WHERE status=0) LIMIT 1
Имеется всего 2 таблицы (импортировать из test_db.sql):
- t1 содержит id и text (генерируемый текст, по возможности уникальный)
- t2 содержит id, t1 (id из t1), status (случайно генерируемое число [0, 2]) Каждая таблица имеет индексы.
Данные для таблиц генерируются скриптом gen-data.php следующим образом: ../gen-data.php?table=NAME&count=COUNT где:
- NAME - название таблицы (t1 или t2, при этом для t2 создаются данные на основании данных в t1)
- COUNT - количество данных * SIZE_PATCH_GEN (config.php)
В subquery-test.php 4 способа получения данных из БД:
- запрос с подзапросом
- формирование запроса с перебросом данных на php (подзапрос выполняется отдельно, его результат преобразуется в список и полученные данные вставляются в основной запрос)
- формирование запроса с перебросом данных на php, при этом список создается на стороне СУБД
- генерация запроса без вложенного подзапроса на стороне СУБД
t1-количество записей, t2-количество записей:
t1-1000, t2-1000:
- 0.00059890747070312
- 0.0016210079193115
- 0.00142502784729
- 0.0018970966339111
t1-101000, t2-101000:
- 0.058974027633667
- 0.16162991523743
- 0.14342308044434
- 0.19108605384827
t1-1101000, t2-1101000:
- 1.1628739833832
- 1.7279899120331
- 1.4494400024414
- 1.9515790939331
В итоге запрос с подзапросом оказался самый быстрый и самый простой в написании. СУБД успешно выполняет оптимизацию запроса, и подзапрос не является коррелированным.