Подразумеваю что всё из статьи «Установка Join Order Benchmark» вы уже выполнили. Значит, у нас в наличии есть:
- База данных imdb
- 21 заполненная данными таблица в ней
- Директория со 113-ю запросами по адресу ~/join-order-benchmark
Давайте попробуем прогнать все эти запросы и получить, например, время их планирования и выполнения. Будем пробовать такой запуск Join Order Benchmark делать автоматизировано. Я буду использовать bash.
Нижеприведенный способ наиболее удобен мне. У вас может быть любой другой способ запуска бенчмарка.
Время планирования и выполнения можно взять при выполнении команды EXPLAIN (ANALYZE). Напомню вывод:
EXPLAIN ANALYZE SELECT 1; QUERY PLAN ------------------------------------------------------------------------------------ Result (cost=0.00..0.01 rows=1 width=4) (actual time=0.005..0.006 rows=1 loops=1) Planning Time: 0.082 ms Execution Time: 0.036 ms (3 rows)
EXPLAIN с опцией ANALYZE реально выполняет запрос и выдает его актуальную информацию. Так что из результата я заберу строки Planning иExecution Time.
Но сначала нужно каждому запросу в их начало дописать строчку EXPLAIN ANALYZE, и тоже можно это сделать скриптом. Например, таким:
#!/bin/bash for var in $(ls ~/join-order-benchmark) do sed -i -e '1 s/^/EXPLAIN ANALYZE\n/;' ~/join-order-benchmark/$var done
Открыв любой запрос из той директории, у вас должно получиться нечто подобное (2a.sql):
EXPLAIN ANALYZE SELECT MIN(t.title) AS movie_title FROM company_name AS cn, keyword AS k, movie_companies AS mc, movie_keyword AS mk, title AS t WHERE cn.country_code ='[de]' AND k.keyword ='character-name-in-title' AND cn.id = mc.company_id AND mc.movie_id = t.id AND t.id = mk.movie_id AND mk.keyword_id = k.id AND mc.movie_id = mk.movie_id;
Подготовительные работы выполнены. Теперь дело за малым — нужно выполнить эти запросы. Для этого я написал небольшой скрипт:
#!/bin/bash #название директории где лежат запросы (для удобства, можно другой каталог с запросами подставить) job_dir="join-order-benchmark" #Очистка прошлых результатов rm -rf results/* rm -rf PlanTime rm -rf ExecTime #выполняю запросы из списка list for var in $(ls ~/$job_dir | grep '^[1-9]') do psql -d imdb -f ~/$job_dir/$var -o results/$var done #Вырезаю нужные строки, сортирую по названию файла, итоговое время сохраняю в файлы grep -r "Planning Time:" results/ | sed 's|.*/||' | sort -n | awk '{print $4}' > PlanTime grep -r "Execution Time:" results/ | sed 's|.*/||' | sort -n | awk '{print $4}' > ExecTime
В том месте, где вы сохраните этот скрипт нужно создать директорию results. В ней будут сохраняться планы получившихся запросов (можно их по отдельности открыть, проверить результаты). Директория со скриптами должна находится по адресу домашняя_папка_пользователя/join-order-benchmark. В скрипте можно поменять адрес директории с запросами, но отсчет идёт от домашней директории.
Скрипт состоит из нескольких частей. Сначала идёт очистка прошлых результатов (если они были), это команда rm -rf.
Далее в цикле я беру все запросы из директории с запросами и выполняю их — последовательно отправляю в psql, результат (вывод команды EXPLAIN ANALYZE) сохраняю в results по названием «выполненный_сценарий.sql».
В последних двух строках я вырезаю время планирования и выполнения из результата; убираю всё лишнее, что стоит до начала номера файла-запроса; сортирую по названию; беру четвертое слово в получившейся строке — это и есть нужное время; сохраняю его в файл результата в том месте, где находится скрипт. Да, по умолчанию, ls выводит в порядке сортировки по возрастанию. Но я добавил команду сортировки для бо́льшей уверенности (ну и чтобы потренироваться).
Оформил эти скрипты в репозитарий на github. Далее планирую его дорабатывать.
Запускаем скрипт, но учтите, что на моём не слабом ноутбуке полная отработка всех запросов заняла около восьми минут. В результате ниже я заменил точки на запятые для удобства дальнейшей обработки.
№ | PlanTime | ExecTime |
1 | 2,796 | 151,13 |
2 | 1,954 | 75,577 |
3 | 1,793 | 82,014 |
4 | 1,785 | 77,022 |
5 | 1,856 | 2023,429 |
6 | 2,666 | 660,542 |
7 | 2,595 | 562,513 |
8 | 8,445 | 1122,937 |
9 | 1,742 | 799,924 |
10 | 2,033 | 142,912 |
11 | 6,675 | 831,726 |
12 | 2,554 | 151,5 |
13 | 8,303 | 124,528 |
14 | 2,058 | 152,515 |
15 | 9,316 | 149,837 |
16 | 2,013 | 116,359 |
17 | 2,174 | 222,239 |
18 | 2,315 | 80,397 |
19 | 2,332 | 392,906 |
20 | 2,587 | 13,392 |
21 | 2,281 | 19865,777 |
22 | 5,273 | 28,747 |
23 | 2,316 | 8913,507 |
24 | 9,11 | 0,154 |
25 | 5,624 | 0,139 |
26 | 6,405 | 0,136 |
27 | 3,949 | 0,127 |
28 | 3,689 | 0,129 |
29 | 4,013 | 0,15 |
30 | 4,231 | 0,151 |
31 | 7,548 | 0,153 |
32 | 8,086 | 0,17 |
33 | 7,681 | 0,33 |
34 | 7,466 | 0,161 |
35 | 5,332 | 3948,828 |
36 | 14,49 | 256,13 |
37 | 4,655 | 21863,245 |
38 | 18,413 | 1118,496 |
39 | 5,842 | 32,143 |
40 | 7,332 | 1123,263 |
41 | 6,682 | 188,742 |
42 | 9,718 | 2502,828 |
43 | 8,957 | 87,616 |
44 | 7,501 | 5191,212 |
45 | 12,289 | 3220,687 |
46 | 13,431 | 492,77 |
47 | 14,293 | 470,69 |
48 | 12,07 | 3456,559 |
49 | 11,272 | 4786,653 |
50 | 7,219 | 213,807 |
51 | 7,346 | 1310,402 |
52 | 20,15 | 448,781 |
53 | 17,933 | 28,445 |
54 | 17,837 | 2774,714 |
55 | 19,324 | 1177,277 |
56 | 16,079 | 1142,521 |
57 | 8,875 | 5,484 |
58 | 7,423 | 4,531 |
59 | 7,348 | 7578,27 |
60 | 11,115 | 57248,93 |
61 | 6,845 | 15389,786 |
62 | 6,2 | 9770,052 |
63 | 5,594 | 9769,129 |
64 | 5,374 | 13549,286 |
65 | 24 | 11868,584 |
66 | 9,843 | 14055,789 |
67 | 6,747 | 1156,89 |
68 | 5,966 | 8221,037 |
69 | 35,273 | 0,216 |
70 | 23,709 | 0,304 |
71 | 27,814 | 0,463 |
72 | 28,628 | 0,201 |
73 | 19,325 | 19338,165 |
74 | 17,384 | 9989,327 |
75 | 23,585 | 2185,361 |
76 | 23,767 | 186,356 |
77 | 23,379 | 88,299 |
78 | 19,433 | 111,482 |
79 | 67,394 | 4037,798 |
80 | 43,659 | 388,092 |
81 | 45,339 | 6466,44 |
82 | 65,024 | 5174,291 |
83 | 41,068 | 1099,025 |
84 | 40,744 | 147,478 |
85 | 41,109 | 10995,183 |
86 | 76,932 | 0,953 |
87 | 66,587 | 0,2 |
88 | 42,106 | 21197,005 |
89 | 16,557 | 254,856 |
90 | 16,627 | 24918,032 |
91 | 102,963 | 59844,804 |
92 | 66,276 | 850,359 |
93 | 67,635 | 20258,037 |
94 | 79,989 | 102,878 |
95 | 67,966 | 8,742 |
96 | 67,201 | 53,91 |
97 | 86,658 | 1872,11 |
98 | 83,361 | 1792,454 |
99 | 87,428 | 679,013 |
100 | 104,021 | 0,293 |
101 | 94,324 | 0,237 |
102 | 102,824 | 0,241 |
103 | 75,006 | 1060,153 |
104 | 69,682 | 324,781 |
105 | 72,273 | 7823,968 |
106 | 62,41 | 1409,851 |
107 | 59,602 | 296,599 |
108 | 60,627 | 1316,261 |
109 | 3,369 | 14,854 |
110 | 2,338 | 200,487 |
111 | 101,152 | 43,329 |
112 | 80,52 | 21,112 |
113 | 80,84 | 100,903 |
Что делать с полученным результатом? Можно, например, вывести вот такой график (использовал Google таблицу для этого):
Синий цвет — это время планирования, красный — выполнения. Размерности разные! Не перепутайте.
Leave a Reply