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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
|
set @subselect_mat_cost=@@optimizer_switch;
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set long_query_time=0.1;
TEST GROUP 1:
Typical cases of in-to-exists and materialization subquery strategies
=====================================================================
drop database if exists world;
set names utf8;
create database world;
use world;
CREATE TABLE Country (
Code char(3) NOT NULL default '',
Name char(52) NOT NULL default '',
SurfaceArea float(10,2) NOT NULL default '0.00',
Population int(11) NOT NULL default '0',
Capital int(11) default NULL,
PRIMARY KEY (Code),
UNIQUE INDEX (Name)
);
CREATE TABLE City (
ID int(11) NOT NULL auto_increment,
Name char(35) NOT NULL default '',
Country char(3) NOT NULL default '',
Population int(11) NOT NULL default '0',
PRIMARY KEY (ID),
INDEX (Population),
INDEX (Country)
);
CREATE TABLE CountryLanguage (
Country char(3) NOT NULL default '',
Language char(30) NOT NULL default '',
Percentage float(3,1) NOT NULL default '0.0',
PRIMARY KEY (Country, Language),
INDEX (Percentage)
);
Make the schema and data more diverse by adding more indexes, nullable
columns, and NULL data.
create index SurfaceArea on Country(SurfaceArea);
create index Language on CountryLanguage(Language);
create index CityName on City(Name);
alter table City change population population int(11) null default 0;
select max(id) from City into @max_city_id;
insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL);
SELECT COUNT(*) FROM Country;
COUNT(*)
239
SELECT COUNT(*) FROM City;
COUNT(*)
4080
SELECT COUNT(*) FROM CountryLanguage;
COUNT(*)
984
set @@optimizer_switch = 'in_to_exists=on,semijoin=on,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on';
1. Subquery in a disjunctive WHERE clause of the outer query.
Q1.1m:
MATERIALIZATION: there are too many rows in the outer query
to be looked up in the inner table.
EXPLAIN
SELECT Name FROM Country
WHERE (Code IN (select Country from City where City.Population > 100000) OR
Name LIKE 'L%') AND
surfacearea > 1000000;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL Name,SurfaceArea NULL NULL NULL 239 Using where
2 MATERIALIZED City ALL Population,Country NULL NULL NULL 4080 Using where
SELECT Name FROM Country
WHERE (Code IN (select Country from City where City.Population > 100000) OR
Name LIKE 'L%') AND
surfacearea > 1000000;
Name
Algeria
Angola
Argentina
Australia
Bolivia
Brazil
Egypt
South Africa
Ethiopia
Indonesia
India
Iran
Canada
Kazakstan
China
Colombia
Congo, The Democratic Republic of the
Libyan Arab Jamahiriya
Mali
Mauritania
Mexico
Mongolia
Niger
Peru
Saudi Arabia
Sudan
Chad
Russian Federation
United States
Q1.1e:
IN-EXISTS: the materialization cost is the same as above, but
there are much fewer outer rows to be looked up, thus the
materialization cost is too high to compensate for fast lookups.
EXPLAIN
SELECT Name FROM Country
WHERE (Code IN (select Country from City where City.Population > 100000) OR
Name LIKE 'L%') AND
surfacearea > 10*1000000;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country range Name,SurfaceArea SurfaceArea 4 NULL 5 Using index condition; Using where; Rowid-ordered scan
2 DEPENDENT SUBQUERY City index_subquery Population,Country Country 3 func 18 Using where
SELECT Name FROM Country
WHERE (Code IN (select Country from City where City.Population > 100000) OR
Name LIKE 'L%') AND
surfacearea > 10*1000000;
Name
Russian Federation
Q1.2m:
MATERIALIZATION: the IN predicate is pushed (attached) to the last table
in the join order (Country, City), therefore there are too many row
combinations to filter by re-executing the subquery for each combination.
EXPLAIN
SELECT *
FROM Country, City
WHERE City.Country = Country.Code AND
Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
(City.Name IN
(select Language from CountryLanguage where Percentage > 50) OR
City.name LIKE '%Island%');
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
1 PRIMARY City ref Country Country 3 world.Country.Code 18 Using where
2 MATERIALIZED CountryLanguage ALL Percentage,Language NULL NULL NULL 984 Using where
SELECT *
FROM Country, City
WHERE City.Country = Country.Code AND
Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
(City.Name IN
(select Language from CountryLanguage where Percentage > 50) OR
City.name LIKE '%Island%');
Code Name SurfaceArea Population Capital ID Name Country population
CCK Cocos (Keeling) Islands 14.00 600 2317 2317 West Island CCK 167
Q1.2e:
IN_EXISTS: join order is the same, but the left IN operand refers to
only the first table in the join order (Country), so there are much
fewer rows to filter by subquery re-execution.
EXPLAIN
SELECT *
FROM Country, City
WHERE City.Country = Country.Code AND
Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
(Country.Name IN
(select Language from CountryLanguage where Percentage > 50) OR
Country.name LIKE '%Island%');
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
1 PRIMARY City ref Country Country 3 world.Country.Code 18
2 DEPENDENT SUBQUERY CountryLanguage index_subquery Percentage,Language Language 30 func 2 Using where
SELECT *
FROM Country, City
WHERE City.Country = Country.Code AND
Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
(Country.Name IN
(select Language from CountryLanguage where Percentage > 50) OR
Country.name LIKE '%Island%');
Code Name SurfaceArea Population Capital ID Name Country population
VGB Virgin Islands, British 151.00 21000 537 537 Road Town VGB 8000
CYM Cayman Islands 264.00 38000 553 553 George Town CYM 19600
COK Cook Islands 236.00 20000 583 583 Avarua COK 11900
FRO Faroe Islands 1399.00 43000 901 901 Tórshavn FRO 14542
CXR Christmas Island 135.00 2500 1791 1791 Flying Fish Cove CXR 700
KIR Kiribati 726.00 83000 2256 2255 Bikenibeu KIR 5055
KIR Kiribati 726.00 83000 2256 2256 Bairiki KIR 2226
CCK Cocos (Keeling) Islands 14.00 600 2317 2316 Bantam CCK 503
CCK Cocos (Keeling) Islands 14.00 600 2317 2317 West Island CCK 167
MHL Marshall Islands 181.00 64000 2507 2507 Dalap-Uliga-Darrit MHL 28000
NRU Nauru 21.00 12000 2728 2727 Yangor NRU 4050
NRU Nauru 21.00 12000 2728 2728 Yaren NRU 559
NFK Norfolk Island 36.00 2000 2806 2806 Kingston NFK 800
PLW Palau 459.00 19000 2881 2881 Koror PLW 12000
MNP Northern Mariana Islands 464.00 78000 2913 2913 Garapan MNP 9200
TCA Turks and Caicos Islands 430.00 17000 3423 3423 Cockburn Town TCA 4800
TUV Tuvalu 26.00 12000 3424 3424 Funafuti TUV 4600
VIR Virgin Islands, U.S. 347.00 93000 4067 4067 Charlotte Amalie VIR 13000
Q1.3:
For the same reasons as in Q2 IN-EXISTS and MATERIALIZATION chosen
for each respective subquery.
EXPLAIN
SELECT City.Name, Country.Name
FROM City,Country
WHERE City.Country = Country.Code AND
Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
((Country.Code, Country.Name) IN
(select Country, Language from CountryLanguage where Percentage > 50) AND
Country.Population > 3000000
OR
(Country.Code, City.Name) IN
(select Country, Language from CountryLanguage));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
1 PRIMARY City ref Country Country 3 world.Country.Code 18 Using where
3 MATERIALIZED CountryLanguage index PRIMARY,Language PRIMARY 33 NULL 984 Using index
2 DEPENDENT SUBQUERY CountryLanguage unique_subquery PRIMARY,Percentage,Language PRIMARY 33 func,func 1 Using where
SELECT City.Name, Country.Name
FROM City,Country
WHERE City.Country = Country.Code AND
Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
((Country.Code, Country.Name) IN
(select Country, Language from CountryLanguage where Percentage > 50) AND
Country.Population > 3000000
OR
(Country.Code, City.Name) IN
(select Country, Language from CountryLanguage));
Name Name
Kigali Rwanda
2. NOT IN subqueries
Q2.1:
Number of cities that are not capitals in countries with small population.
MATERIALIZATION is 50 times faster because the cost of each subquery
re-execution is much higher than the cost of index lookups into the
materialized subquery.
EXPLAIN
select count(*) from City
where City.id not in (select capital from Country
where capital is not null and population < 100000);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY City index NULL PRIMARY 4 NULL 4080 Using where; Using index
2 MATERIALIZED Country ALL NULL NULL NULL NULL 239 Using where
Q2.2e:
Countries that speak French, but do not speak English
IN-EXISTS because the outer query filters many rows, thus
there are few lookups to make.
EXPLAIN
SELECT Country.Name
FROM Country, CountryLanguage
WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
AND CountryLanguage.Language = 'French'
AND Code = Country;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage ref PRIMARY,Language Language 30 const 20 Using index condition
1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where
2 DEPENDENT SUBQUERY CountryLanguage unique_subquery PRIMARY,Language PRIMARY 33 func,const 1 Using index; Using where
SELECT Country.Name
FROM Country, CountryLanguage
WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
AND CountryLanguage.Language = 'French'
AND Code = Country;
Name
France
Saint Pierre and Miquelon
Belgium
Burundi
Guadeloupe
Haiti
Madagascar
Martinique
Mayotte
French Polynesia
Rwanda
Sao Tome and Principe
Switzerland
New Caledonia
Lebanon
Mauritius
Andorra
Italy
Luxembourg
Q2.2m:
Countries that speak French OR Spanish, but do not speak English
MATERIALIZATION because the outer query filters less rows than Q5-a,
so there are more lookups.
EXPLAIN
SELECT Country.Name
FROM Country, CountryLanguage
WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
AND Code = Country;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage range PRIMARY,Language Language 30 NULL 45 Using index condition; Using where; Rowid-ordered scan
1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where
2 MATERIALIZED CountryLanguage ref PRIMARY,Language Language 30 const 47 Using index condition
SELECT Country.Name
FROM Country, CountryLanguage
WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
AND Code = Country;
Name
Andorra
Argentina
Bolivia
Chile
Costa Rica
Dominican Republic
Ecuador
El Salvador
Spain
Guatemala
Honduras
Colombia
Cuba
Mexico
Nicaragua
Panama
Paraguay
Peru
France
Saint Pierre and Miquelon
Uruguay
Venezuela
Belgium
Burundi
Guadeloupe
Haiti
Madagascar
Martinique
Mayotte
French Polynesia
Rwanda
Sao Tome and Principe
Switzerland
New Caledonia
Lebanon
Mauritius
Andorra
Italy
Luxembourg
France
Sweden
Q2.3e:
Not a very meaningful query that tests NOT IN.
IN-EXISTS because the outer query is cheap enough to reexecute many times.
EXPLAIN
select count(*)
from CountryLanguage
where (Language, Country) NOT IN
(SELECT City.Name, Country.Code
FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
AND Language IN ('English','Spanish');
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage range Language Language 30 NULL 72 Using index condition; Using where; Rowid-ordered scan
2 DEPENDENT SUBQUERY City ref CityName CityName 35 func 1 Using index condition; Using where
2 DEPENDENT SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using index
select count(*)
from CountryLanguage
where (Language, Country) NOT IN
(SELECT City.Name, Country.Code
FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
AND Language IN ('English','Spanish');
count(*)
88
Q2.3m:
MATERIALIZATION with the PARTIAL_MATCH_MERGE strategy, because the HAVING
clause prevents the use of the index on City(Name), and in practice reduces
radically the size of the temp table.
EXPLAIN
select count(*)
from CountryLanguage
where (Language, Country) NOT IN
(SELECT City.Name, Country.Code
FROM City LEFT JOIN Country ON (Country = Code)
HAVING City.Name LIKE "Santa%");
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage index NULL PRIMARY 33 NULL 984 Using where; Using index
2 MATERIALIZED City ALL NULL NULL NULL NULL 4080
2 MATERIALIZED Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using index
select count(*)
from CountryLanguage
where (Language, Country) NOT IN
(SELECT City.Name, Country.Code
FROM City LEFT JOIN Country ON (Country = Code)
HAVING City.Name LIKE "Santa%");
count(*)
984
3. Subqueries with GROUP BY, HAVING, and aggregate functions
Q3.1:
Languages that are spoken in countries with 10 or 11 languages
MATERIALIZATION is about 100 times faster than IN-EXISTS.
EXPLAIN
select count(*)
from CountryLanguage
where
(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
WHERE Code = Country GROUP BY Code)
OR
(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
WHERE Code = Country GROUP BY Code)
order by Country;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage index NULL PRIMARY 33 NULL 984 Using where; Using index
3 MATERIALIZED CountryLanguage index PRIMARY PRIMARY 33 NULL 984 Using index; Using temporary
3 MATERIALIZED Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index
2 MATERIALIZED CountryLanguage index PRIMARY PRIMARY 33 NULL 984 Using index; Using temporary
2 MATERIALIZED Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index
select count(*)
from CountryLanguage
where
(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
WHERE Code = Country GROUP BY Code)
OR
(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
WHERE Code = Country GROUP BY Code)
order by Country;
count(*)
102
Q3.2:
Countries whose capital is a city name that names more than one
cities.
MATERIALIZATION because the cost of single subquery execution is
close to that of materializing the subquery.
EXPLAIN
select * from Country, City
where capital = id and
(City.name in (SELECT name FROM City
GROUP BY name HAVING Count(*) > 2) OR
capital is null);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL NULL NULL NULL NULL 239 Using where
1 PRIMARY City eq_ref PRIMARY PRIMARY 4 world.Country.Capital 1 Using where
2 MATERIALIZED City index NULL CityName 35 NULL 4080 Using index
select * from Country, City
where capital = id and
(City.name in (SELECT name FROM City
GROUP BY name HAVING Count(*) > 2) OR
capital is null);
Code Name SurfaceArea Population Capital ID Name Country population
BMU Bermuda 53.00 65000 191 191 Hamilton BMU 1200
BOL Bolivia 1098581.00 8329000 194 194 La Paz BOL 758141
CRI Costa Rica 51100.00 4023000 584 584 San José CRI 339131
HKG Hong Kong 1075.00 6782000 937 937 Victoria HKG 1312637
SYC Seychelles 455.00 77000 3206 3206 Victoria SYC 41000
Q3.3: MATERIALIZATION is 25 times faster than IN-EXISTS
EXPLAIN
SELECT Name
FROM Country
WHERE Country.Code NOT IN
(SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL NULL NULL NULL NULL 239 Using where
2 MATERIALIZED City ALL NULL NULL NULL NULL 4080 Using temporary
SELECT Name
FROM Country
WHERE Country.Code NOT IN
(SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
Name
Antigua and Barbuda
Costa Rica
Montserrat
Norfolk Island
Seychelles
Antarctica
Bouvet Island
British Indian Ocean Territory
South Georgia and the South Sandwich Islands
Heard Island and McDonald Islands
French Southern territories
United States Minor Outlying Islands
4. Subqueries in the SELECT and HAVING clauses
Q4.1m:
Capital information about very big cities
MATERIALIZATION
EXPLAIN
select Name, City.id in (select capital from Country where capital is not null) as is_capital
from City
where City.population > 10000000;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY City range Population Population 5 NULL 4 Using index condition; Rowid-ordered scan
2 MATERIALIZED Country ALL NULL NULL NULL NULL 239 Using where
select Name, City.id in (select capital from Country where capital is not null) as is_capital
from City
where City.population > 10000000;
Name is_capital
Mumbai (Bombay) 0
Q4.1e:
IN-TO-EXISTS after adding an index to make the subquery re-execution
efficient.
create index CountryCapital on Country(capital);
EXPLAIN
select Name, City.id in (select capital from Country where capital is not null) as is_capital
from City
where City.population > 10000000;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY City range Population Population 5 NULL 4 Using index condition; Rowid-ordered scan
2 SUBQUERY Country index_subquery CountryCapital CountryCapital 5 func 2 Using index; Using where
select Name, City.id in (select capital from Country where capital is not null) as is_capital
from City
where City.population > 10000000;
Name is_capital
Mumbai (Bombay) 0
drop index CountryCapital on Country;
Q4.2:
MATERIALIZATION
EXPLAIN
SELECT City.Name, City.Population
FROM City JOIN Country ON City.Country = Country.Code
GROUP BY City.Name
HAVING City.Name IN (select Name from Country where population < 1000000);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country index PRIMARY PRIMARY 3 NULL 239 Using index; Using temporary; Using filesort
1 PRIMARY City ref Country Country 3 world.Country.Code 18
2 MATERIALIZED Country ALL Name NULL NULL NULL 239 Using where
SELECT City.Name, City.Population
FROM City JOIN Country ON City.Country = Country.Code
GROUP BY City.Name
HAVING City.Name IN (select Name from Country where population < 1000000);
Name Population
Djibouti 383000
Gibraltar 27025
Macao 437500
San Marino 2294
5. Subqueries with UNION
Q5.1:
EXPLAIN
SELECT * from City where (Name, 91) in
(SELECT Name, round(Population/1000)
FROM City
WHERE Country = "IND" AND Population > 2500000
UNION
SELECT Name, round(Population/1000)
FROM City
WHERE Country = "IND" AND Population < 100000);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY City ALL NULL NULL NULL NULL 4080 Using where
2 DEPENDENT SUBQUERY City ref Population,Country,CityName CityName 35 func 1 Using where
3 DEPENDENT UNION City ref Population,Country,CityName CityName 35 func 1 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
SELECT * from City where (Name, 91) in
(SELECT Name, round(Population/1000)
FROM City
WHERE Country = "IND" AND Population > 2500000
UNION
SELECT Name, round(Population/1000)
FROM City
WHERE Country = "IND" AND Population < 100000);
ID Name Country population
1359 Hassan IND 90803
1360 Ambala Sadar IND 90712
1361 Baidyabati IND 90601
set @@optimizer_switch='default';
drop database world;
TEST GROUP 2:
Tests of various combinations of optimizer switches, types of queries,
available indexes, column nullability, constness of tables/predicates.
=====================================================================
set optimizer_switch=@subselect_mat_cost;
|