Skip to content

Commit 8d7839d

Browse files
ulya-sidorinaIuliia Sidorinablinkov
authored
docs(ydb): translate query plan documentation (#3442)
Co-authored-by: Iuliia Sidorina <ulya-sidorina@nb-c02f25spmd6r.barn-sun.ts.net> Co-authored-by: Ivan Blinkov <ivan@blinkov.ru>
1 parent 4b36f7a commit 8d7839d

File tree

13 files changed

+264
-3
lines changed

13 files changed

+264
-3
lines changed
56.8 KB
Loading
46.8 KB
Loading
48.1 KB
Loading
163 KB
Loading
180 KB
Loading
Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,101 @@
1-
{% include [no-translation](../_includes/alerts/no-translation.md) %}
1+
# Query plan optimization
2+
3+
Before executing a query, it is essential to analyze its execution plan to detect and eliminate the reasons for possible excessive cluster resource consumption or abnormally high execution time. This article will discuss specific examples of query plan analysis.
4+
5+
Let's consider the following query that searches for episodes by title:
6+
7+
``` sql
8+
SELECT season_id, episode_id
9+
FROM episodes
10+
WHERE title = 'The Work Outing'
11+
```
12+
13+
Schema of the `episodes` table:
14+
15+
![episodes](../_assets/episodes_scheme.png)
16+
17+
Let's build a plan for this query. You can do this via either UI or {{ ydb-short-name }} CLI:
18+
19+
{% list tabs %}
20+
21+
- {{ ydb-short-name }} CLI
22+
23+
You can build a query plan via {{ ydb-short-name }} [CLI](../reference/ydb-cli/_includes/index.md) using the following command:
24+
```
25+
ydb -p <profile_name> table query explain \
26+
-q "SELECT season_id, episode_id
27+
FROM episodes
28+
WHERE title = 'The Work Outing'"
29+
```
30+
31+
Result:
32+
```
33+
Query Plan:
34+
ResultSet
35+
└──Limit (Limit: 1001)
36+
└──<UnionAll>
37+
└──Limit (Limit: 1001)
38+
└──Filter (Predicate: item.title == "The Work Outing")
39+
└──TableFullScan (ReadRanges: ["series_id (-∞, +∞)","season_id (-∞, +∞)","episode_id (-∞, +∞)"], ReadColumns: ["episode_id","season_id","title"], Table: episodes)
40+
Tables: ["episodes"]
41+
```
42+
43+
- Embedded UI
44+
45+
You can also build a query plan via [Embedded UI](../reference/embedded-ui/ydb-monitoring.md). You need to navigate to the database page, go to the `Query` section, type the query text, and click on `Explain`:
46+
47+
![explain_ui](../_assets/explain_ui.png)
48+
49+
Result:
50+
51+
![query_plan_ui](../_assets/query_plan_ui.png)
52+
53+
{% endlist %}
54+
55+
Both plan representations contain the result being returned to the client at the root, table operations at the leaves, and data transformations at the intermediate nodes. It is important to pay attention to the node containing the table reading operation. In this case, it is a `TableFullScan` for the `episodes` table. Full table scans consume time and resources proportional to the size of the table, so it is advisable to avoid them whenever possible in tables that tend to grow over time or are simply large.
56+
57+
One typical approach to avoid full scans is using a [secondary index](secondary-indexes.md). In this case, it makes sense to add a secondary index for the column `title` using the following query:
58+
59+
``` sql
60+
ALTER TABLE episodes
61+
ADD INDEX title_index GLOBAL ON (title)
62+
```
63+
64+
Please note that this example uses [synchronous secondary index](../concepts/_includes/secondary_indexes.md#sync). Building an index in {{ ydb-short-name }} is an asynchronous operation. Even if the index creation query is successful, it is advisable to wait for some time because the index may not be ready for use immediately. You can manage asynchronous operations through the [CLI](../reference/ydb-cli/commands/_includes/secondary_index.md#add).
65+
66+
Let's build the query plan using the secondary index `title_index`. Secondary indexes to be used need to be explicitly specified in the `VIEW` clause.
67+
68+
{% list tabs %}
69+
70+
- {{ ydb-short-name }} CLI
71+
72+
Command:
73+
```
74+
ydb -p <profile_name> table query explain \
75+
-q "SELECT season_id, episode_id
76+
FROM episodes VIEW title_index
77+
WHERE title = 'The Work Outing'"
78+
```
79+
80+
Result:
81+
```
82+
Query Plan:
83+
ResultSet
84+
└──Limit (Limit: 1001)
85+
└──<UnionAll>
86+
└──Limit (Limit: 1001)
87+
└──Filter (Predicate: Exist(item.title))
88+
└──TablePointLookup (ReadRange: ["title (The Work Outing)","series_id (-∞, +∞)","season_id (-∞, +∞)","episode_id (-∞, +∞)"], ReadLimit: 1001, ReadColumns: ["episode_id","season_id","title"], Table: episodes/title_index/indexImplTable)
89+
Tables: ["episodes/title_index/indexImplTable"]
90+
```
91+
- Embedded UI
92+
93+
![explain_ui](../_assets/explain_with_index_ui.png)
94+
95+
Result:
96+
97+
![query_plan_ui](../_assets/query_plan_with_index_ui.png)
98+
99+
{% endlist %}
100+
101+
The secondary index allowed the query to be executed without fully scanning the main table. Instead of a `TableFullScan,` we received a `TablePointLookup`—reading the index table by key. We no longer need to read the main table because all necessary columns are contained in the index table.

ydb/docs/en/core/dev/toc_p.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ items:
1919
href: secondary-indexes.md
2020
- name: Query plans optimization
2121
href: query-plans-optimization.md
22-
hidden: true
2322
- name: Batch upload
2423
href: batch-upload.md
2524
- name: Paging
8.83 KB
Loading
8.91 KB
Loading
7.86 KB
Loading

0 commit comments

Comments
 (0)