-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtopic_10_Indexing.sql
More file actions
168 lines (121 loc) · 5.14 KB
/
Copy pathtopic_10_Indexing.sql
File metadata and controls
168 lines (121 loc) · 5.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
## create index based on queries rather than on tables
## index are stored in binary trees
use sql_store;
explain select customer_id from customers where state = 'CA';
create index idx_state on customers (state);
create index idx_points on customers (points);
analyze table customers;
show indexes in customers;
## prefix index:
create index idx_lastname on customers (last_name(20));
# determine the lenght of characters included in index:
select
count(distinct left(last_name, 1))
, count(distinct left(last_name, 5))
, count(distinct left(last_name, 10))
from customers;
use sql_blog;
## full text index:
## natural language mode:
create fulltext index idx_title_body on posts (title, body);
select *, match(title, body) against('react redux')
from posts
where match(title, body) against('react redux'); # return any posts that have one or both of these keywords in the title or body.
select *, match(title, body) against('react redux')
from posts
where match(title, body) against('react -redux' in boolean mode); # return any posts that have react but not redux
select *, match(title, body) against('react redux')
from posts
where match(title, body) against('react -redux +form' in boolean mode); # return any posts that have react but not redux, must have form in title/body.
select *, match(title, body) against('react redux')
from posts
where match(title, body) against('"handling a form"' in boolean mode); # having exactly "handling a form" in title/body.
## composite indexes:
use sql_store;
show indexes in customers;
# mutltiple indexes only do half job if filter on two columns.
# also more indexes will slow the write operations and takes more space.
explain select customer_id from customers
where state = 'CA' and points < 1000;
# composite indexes help faster query and sort:
create index idx_state_points on customers (state, points);
explain select customer_id from customers
where state = 'CA' and points < 1000;
# mysql allows composite index of up to 16 columns, genearlly 4 to 6 is optimized.
# drop indexes:
drop index idx_state on customers;
## order of columns in indexes:
# most frequently used columns come first
# columns with higher cardinality (number of unique values in the index) first. (not always the best practice, should always take the queries into account)
# query with more selective conditions come first in indexes.
create index idx_lastname_state on customers (last_name, state);
create index idx_state_lastname on customers (state, last_name);
explain select customer_id from customers
use index (idx_lastname_state)
where state = 'CA' and points < 1000;
# compare the below queries:
explain select customer_id from customers
use index (idx_lastname_state)
where state = 'NY' and last_name like 'A%';
explain select customer_id from customers
use index (idx_state_lastname)
where state = 'NY' and last_name like 'A%';
## when indexes are ignored:
explain select customer_id from customers
where state = 'CA' or points > 1000;
# all rows are scaned but it is still faster because it uses index (not reading data from disk)
# further optimization:
explain
select customer_id from customers
where state = 'CA'
union
select customer_id from customers
where points > 1000;
# whenever we use columns in expersion, mysql is not able to use indexes:
explain
select customer_id from customers
where points + 10 > 2000;
## use indexes for sorting data:
show indexes in customers;
drop index idx_points on customers;
drop index idx_state_lastname on customers;
drop index idx_lastname_state on customers;
explain select customer_id from customers order by state;
explain select customer_id from customers order by first_name;
# file sort is an expensive operation
show status;
explain select customer_id from customers order by state;
show status like 'last_query_cost';
explain select customer_id from customers
order by state, points;
explain select customer_id from customers
order by state, first_name, points;
# as first_name is not in index, this query will use filesort.
explain select customer_id from customers
order by state, points desc;
show status like 'last_query_cost';
# sorting points desc is not using index but file sort so this is an expensive query.
explain select customer_id from customers
order by state desc, points desc;
show status like 'last_query_cost';
explain select customer_id from customers
order by points;
show status like 'last_query_cost';
# because the index (state, points) are sorted first based on state, within each state sort based on points
# we cannot rely on this index to sort points.alter.
# but we can do the following:
explain select customer_id from customers
where state = 'CA'
order by points;
show status like 'last_query_cost';
## covering indexes: (an index that covering all columns an query needs, mysql can execute the query without touching the table)
# selecting all columns is an expensive query:
explain select * from customers
order by state;
show status like 'last_query_cost';
## index maintenance:
# drop duplicate, reduandant and unused indexes.
# duplicate indexes: (a, b, c) (a, b, c)
# redundant indexes: (a, b) (a)
# non-redundant: (a, b) (b)
# non-redundant: (a, b) (b, a)