0

План запроса

26.04.2022

Когда вы обращаетесь к БД, оптимизатор запросов YDB пытается составить наилучший, по его мнению, план выполнения запроса.Чтобы оптимизировать свои запросы к БД с точки зрения скорости их выполнения (и/или стоимости, что актуально для бессерверного режима YDB), нужно получить и проанализировать этот план. Вы можете это сделать через консоль управления или с помощью YDB CLI.Давайте разберем план запроса, который мы использовали на прошлом уроке в качестве примера объединения таблиц.

Скопировать кодSELECT 
    sa.title AS season_title, 
    sr.title AS series_title, 
    sr.series_id, sa.season_id 
FROM seasons AS sa 
INNER JOIN series AS sr ON sa.series_id = sr.series_id 
WHERE sa.season_id = 1  

Войдите в редактор SQL вашей БД и вставьте в поле ввода текст запроса. Нажмите на стрелку справа от кнопки Выполнить и в выпадающем меню выберите опцию Explain.

image

В результате внизу отобразится поле, содержащее план запроса.

Скопировать кодQuery plan: 
{ 
    meta : { 
        version : "0.1", 
        type : query 
    }, 
    tables : [ 
        { 
            name : "/ru-central1/b1g4ej5ju4rf5kelpk4b/etn01lrprvnlnhv8v5kj/seasons", 
            reads : [ 
                { 
                    type : FullScan, 
                    scan_by : [ 
                        series_id, 
                        season_id 
                    ], 
                    columns : [ 
                        season_id, 
                        series_id, 
                        title 
                    ] 
                } 
            ] 
        }, 
        { 
            name : "/ru-central1/b1g4ej5ju4rf5kelpk4b/etn01lrprvnlnhv8v5kj/series", 
            reads : [ 
                { 
                    type : MultiLookup, 
                    lookup_by : [ 
                        "series_id (expr)" 
                    ], 
                    columns : [ 
                        series_id, 
                        title 
                    ] 
                } 
            ] 
        } 
    ] 
} 

Основная секция (tables) плана запроса содержит информацию об обращениях к таблицам. Операция чтения описываются в разделе reads, а операции записи — в разделе writes (в этом плане запроса данный раздел отсутствует).Ключевой характеристикой любого обращения к таблице является его тип.Типы чтения:

  • FullScan — полное сканирование таблицы, читаются все записи на всех шардах;
  • Scan — читается определенный диапазон записей;
  • Lookup — чтение по ключу или префиксу ключа;
  • MultiLookup — множественные чтения по ключу или префиксу ключа (такой тип обращения возможен, например при выполнении инструкций JOIN).

Типы записи:

  • Upsert — добавление одной записи;
  • MultiUpsert — добавление нескольких записей;
  • Erase — единичное удаление по ключу;
  • MultiErase — множественные удаления.

Рассмотрим план запроса из нашего примера.Параметр lookup_by показывает, по каким колонкам (ключу или префиксу ключа) выполняется чтение. Параметр scan_by показывает, по каким колонкам выполняется scan, то есть чтение всех записей в определенном диапазоне значений. В columns перечислены колонки, значения которых будут считываться из таблицы.Из плана запроса следует, что для таблицы seasons будет выполнен FullScan, а для таблицы series — множественные чтения (тип обращения MultiLookup) по ключу series_id (lookup_by). Это говорит нам  о том, что данный запрос составлен не лучшим образом. Тип чтения FullScan означает, что для выполнения запроса потребуется полностью прочитать всю таблицу. Если таблица большая, то такой запрос приведет к избыточному росту нагрузки на БД и задержкам, а в режиме serverless — еще и к повышенным расходам.

Свежие комментарии

Подписка

Лучшие статьи


Fatal error: Uncaught Error: Call to a member function have_posts() on null in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php:380 Stack trace: #0 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/widget.php(257): fox56_blog_grid(NULL, Array) #1 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/register.php(33): include('/home/host18670...') #2 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/class-wp-widget.php(394): Wi_Widget_Latest_Posts->widget(Array, Array) #3 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/widgets.php(837): WP_Widget->display_callback(Array, Array) #4 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(417): dynamic_sidebar('sidebar') #5 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(136): fox56_single_sidebar() #6 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(7): fox56_single_inner() #7 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/single.php(23): fox56_single() #8 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/template-loader.php(106): include('/home/host18670...') #9 /home/host1867038/the-devops.ru/htdocs/www/wp-blog-header.php(19): require_once('/home/host18670...') #10 /home/host1867038/the-devops.ru/htdocs/www/index.php(17): require('/home/host18670...') #11 {main} thrown in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php on line 380