Skip to content

Commit 00d42d2

Browse files
author
Steinar H. Gunderson
committed
Bug #29634179: STREAM DATA WITHOUT TEMPORARY MATERIALIZATION
There are certain cases where we currently materialize, but don't need to: - If doing a sort at the end of a join (e.g. for grouping), and we don't sort by row IDs, we can just stream the data directly from the correct iterator into the SortingIterator. (This is now possible to know, since after the fix for #29595346, we know when creating the SortingIterator whether it will be by row IDs or not.) - If materializing a derived table that we don't intend to read from multiple times, and would only table scan. Fix both cases by means of a new StreamingIterator that does the required copying of fields and nothing else. Note that since we now decide ahead-of-time whether we want to sort by row IDs or not, we have somewhat less information; we don't necessarily know the number of rows to sort (used for priority queue decisions), and there are a few cases where it would be slightly better to sort by row ID that we now do not. The benefits from the more common cases should be more than enough to offset this. In the process, we remove the default arguments from the Filesort constructor; they are discouraged by the style guide, and made the code hard to read. Change-Id: I4019c5e1fe1aac95fe1e7c343f3700090f59aac4
1 parent 746b676 commit 00d42d2

32 files changed

+589
-478
lines changed

mysql-test/r/derived_correlated.result

+4-6
Original file line numberDiff line numberDiff line change
@@ -2057,12 +2057,10 @@ EXPLAIN
20572057
-> Table scan on t1
20582058
-> Table scan on dt3
20592059
-> Materialize (invalidate on row from t1)
2060-
-> Table scan on dt2
2061-
-> Temporary table
2062-
-> Limit: 1 row(s)
2063-
-> Table scan on dt
2064-
-> Temporary table
2065-
-> Table scan on t2
2060+
-> Stream results
2061+
-> Limit: 1 row(s)
2062+
-> Stream results
2063+
-> Table scan on t2
20662064

20672065
Warnings:
20682066
Note 1276 Field or reference 'test.t1.a' of SELECT #4 was resolved in SELECT #1

mysql-test/r/explain_tree.result

+2-3
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,8 @@ INSERT INTO t1 VALUES ( 3 );
331331
EXPLAIN FORMAT=tree SELECT ( SELECT f1 FROM t1 AS inner_t1 WHERE inner_t1.f1 > t1.f1 LIMIT 1 ) AS tmp1 FROM t1 ORDER BY tmp1;
332332
EXPLAIN
333333
-> Sort: <temporary>.tmp1
334-
-> Table scan on <temporary>
335-
-> Temporary table
336-
-> Index scan on t1 using PRIMARY
334+
-> Stream results
335+
-> Index scan on t1 using PRIMARY
337336
-> Select #2 (subquery in projection; dependent)
338337
-> Limit: 1 row(s)
339338
-> Filter: (inner_t1.f1 > t1.f1)

mysql-test/r/group_by.result

+3-4
Original file line numberDiff line numberDiff line change
@@ -3824,10 +3824,9 @@ INSERT INTO t1 VALUES ( 3, 5 );
38243824
EXPLAIN FORMAT=tree SELECT f1, f1 + 1, COUNT(DISTINCT f2) AS x FROM t1 GROUP BY f1 ORDER BY x;
38253825
EXPLAIN
38263826
-> Sort: <temporary>.x
3827-
-> Table scan on <temporary>
3828-
-> Temporary table
3829-
-> Group aggregate: count(distinct t1.f2)
3830-
-> Index scan on t1 using k1
3827+
-> Stream results
3828+
-> Group aggregate: count(distinct t1.f2)
3829+
-> Index scan on t1 using k1
38313830

38323831
SELECT f1, f1 + 1, COUNT(DISTINCT f2) AS x FROM t1 GROUP BY f1 ORDER BY x;
38333832
f1 f1 + 1 x

mysql-test/r/myisam_explain_json_non_select_all.result

-2
Original file line numberDiff line numberDiff line change
@@ -3944,7 +3944,6 @@ Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`t
39443944
# Status of "equivalent" SELECT query execution:
39453945
Variable_name Value
39463946
Handler_read_key 4
3947-
Handler_read_rnd 1
39483947
Handler_read_rnd_next 27
39493948
Sort_rows 1
39503949
Sort_scan 1
@@ -4962,7 +4961,6 @@ Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`t
49624961
# Status of "equivalent" SELECT query execution:
49634962
Variable_name Value
49644963
Handler_read_key 4
4965-
Handler_read_rnd 1
49664964
Handler_read_rnd_next 27
49674965
Sort_rows 1
49684966
Sort_scan 1

mysql-test/r/myisam_explain_json_non_select_none.result

-2
Original file line numberDiff line numberDiff line change
@@ -3977,7 +3977,6 @@ Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`t
39773977
# Status of "equivalent" SELECT query execution:
39783978
Variable_name Value
39793979
Handler_read_key 4
3980-
Handler_read_rnd 1
39813980
Handler_read_rnd_next 27
39823981
Sort_rows 1
39833982
Sort_scan 1
@@ -4995,7 +4994,6 @@ Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`t
49954994
# Status of "equivalent" SELECT query execution:
49964995
Variable_name Value
49974996
Handler_read_key 4
4998-
Handler_read_rnd 1
49994997
Handler_read_rnd_next 27
50004998
Sort_rows 1
50014999
Sort_scan 1

mysql-test/r/myisam_explain_non_select_all.result

-2
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,6 @@ Variable_name Value
11721172
# Status of "equivalent" SELECT query execution:
11731173
Variable_name Value
11741174
Handler_read_key 4
1175-
Handler_read_rnd 1
11761175
Handler_read_rnd_next 27
11771176
Sort_rows 1
11781177
Sort_scan 1
@@ -1543,7 +1542,6 @@ Variable_name Value
15431542
# Status of "equivalent" SELECT query execution:
15441543
Variable_name Value
15451544
Handler_read_key 4
1546-
Handler_read_rnd 1
15471545
Handler_read_rnd_next 27
15481546
Sort_rows 1
15491547
Sort_scan 1

mysql-test/r/myisam_explain_non_select_none.result

-2
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,6 @@ Variable_name Value
11711171
# Status of "equivalent" SELECT query execution:
11721172
Variable_name Value
11731173
Handler_read_key 4
1174-
Handler_read_rnd 1
11751174
Handler_read_rnd_next 27
11761175
Sort_rows 1
11771176
Sort_scan 1
@@ -1542,7 +1541,6 @@ Variable_name Value
15421541
# Status of "equivalent" SELECT query execution:
15431542
Variable_name Value
15441543
Handler_read_key 4
1545-
Handler_read_rnd 1
15461544
Handler_read_rnd_next 27
15471545
Sort_rows 1
15481546
Sort_scan 1

mysql-test/r/single_delete_update.result

+2-2
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ Handler_read_key 0
277277
Handler_read_last 0
278278
Handler_read_next 0
279279
Handler_read_prev 0
280-
Handler_read_rnd 1
280+
Handler_read_rnd 0
281281
Handler_read_rnd_next 27
282282
FLUSH STATUS;
283283
DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
@@ -835,7 +835,7 @@ Handler_read_key 0
835835
Handler_read_last 0
836836
Handler_read_next 0
837837
Handler_read_prev 0
838-
Handler_read_rnd 1
838+
Handler_read_rnd 0
839839
Handler_read_rnd_next 27
840840
FLUSH STATUS;
841841
UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5;

mysql-test/r/subquery_sj_all_bka_nixbnl.result

+12-13
Original file line numberDiff line numberDiff line change
@@ -12488,19 +12488,18 @@ ORDER BY col_int_key
1248812488
;
1248912489
EXPLAIN
1249012490
-> Sort: <temporary>.col_int_key
12491-
-> Table scan on <temporary>
12492-
-> Temporary table
12493-
-> Nested loop inner join
12494-
-> Remove duplicates from input sorted on col_int_key
12495-
-> Filter: (t3.col_int is null)
12496-
-> Nested loop left join
12497-
-> Index scan on t1 using col_int_key
12498-
-> Limit: 1 row(s)
12499-
-> Nested loop inner join
12500-
-> Single-row index lookup on t2 using PRIMARY (pk=t1.pk)
12501-
-> Index lookup on t3 using col_int_key (col_int_key=t2.col_int)
12502-
-> Filter: (t4.col_int_key = t1.col_int_key)
12503-
-> Table scan on t4
12491+
-> Stream results
12492+
-> Nested loop inner join
12493+
-> Remove duplicates from input sorted on col_int_key
12494+
-> Filter: (t3.col_int is null)
12495+
-> Nested loop left join
12496+
-> Index scan on t1 using col_int_key
12497+
-> Limit: 1 row(s)
12498+
-> Nested loop inner join
12499+
-> Single-row index lookup on t2 using PRIMARY (pk=t1.pk)
12500+
-> Index lookup on t3 using col_int_key (col_int_key=t2.col_int)
12501+
-> Filter: (t4.col_int_key = t1.col_int_key)
12502+
-> Table scan on t4
1250412503

1250512504
SELECT *
1250612505
FROM t4

mysql-test/r/subquery_sj_loosescan_bka_nixbnl.result

+12-13
Original file line numberDiff line numberDiff line change
@@ -12388,19 +12388,18 @@ ORDER BY col_int_key
1238812388
;
1238912389
EXPLAIN
1239012390
-> Sort: <temporary>.col_int_key
12391-
-> Table scan on <temporary>
12392-
-> Temporary table
12393-
-> Nested loop inner join
12394-
-> Remove duplicates from input sorted on col_int_key
12395-
-> Filter: (t3.col_int is null)
12396-
-> Nested loop left join
12397-
-> Index scan on t1 using col_int_key
12398-
-> Limit: 1 row(s)
12399-
-> Nested loop inner join
12400-
-> Single-row index lookup on t2 using PRIMARY (pk=t1.pk)
12401-
-> Index lookup on t3 using col_int_key (col_int_key=t2.col_int)
12402-
-> Filter: (t4.col_int_key = t1.col_int_key)
12403-
-> Table scan on t4
12391+
-> Stream results
12392+
-> Nested loop inner join
12393+
-> Remove duplicates from input sorted on col_int_key
12394+
-> Filter: (t3.col_int is null)
12395+
-> Nested loop left join
12396+
-> Index scan on t1 using col_int_key
12397+
-> Limit: 1 row(s)
12398+
-> Nested loop inner join
12399+
-> Single-row index lookup on t2 using PRIMARY (pk=t1.pk)
12400+
-> Index lookup on t3 using col_int_key (col_int_key=t2.col_int)
12401+
-> Filter: (t4.col_int_key = t1.col_int_key)
12402+
-> Table scan on t4
1240412403

1240512404
SELECT *
1240612405
FROM t4

mysql-test/r/subquery_sj_mat_bka_nixbnl.result

+13-14
Original file line numberDiff line numberDiff line change
@@ -12708,20 +12708,19 @@ ORDER BY col_int_key
1270812708
;
1270912709
EXPLAIN
1271012710
-> Sort: <temporary>.col_int_key
12711-
-> Table scan on <temporary>
12712-
-> Temporary table
12713-
-> Nested loop inner join
12714-
-> Table scan on <subquery2>
12715-
-> Materialize with deduplication
12716-
-> Filter: (t1.col_int_key is not null)
12717-
-> Filter: (t3.col_int is null)
12718-
-> Nested loop left join
12719-
-> Index scan on t1 using col_int_key
12720-
-> Nested loop inner join
12721-
-> Single-row index lookup on t2 using PRIMARY (pk=t1.pk)
12722-
-> Index lookup on t3 using col_int_key (col_int_key=t2.col_int)
12723-
-> Filter: (t4.col_int_key = `<subquery2>`.col_int_key)
12724-
-> Table scan on t4
12711+
-> Stream results
12712+
-> Nested loop inner join
12713+
-> Table scan on <subquery2>
12714+
-> Materialize with deduplication
12715+
-> Filter: (t1.col_int_key is not null)
12716+
-> Filter: (t3.col_int is null)
12717+
-> Nested loop left join
12718+
-> Index scan on t1 using col_int_key
12719+
-> Nested loop inner join
12720+
-> Single-row index lookup on t2 using PRIMARY (pk=t1.pk)
12721+
-> Index lookup on t3 using col_int_key (col_int_key=t2.col_int)
12722+
-> Filter: (t4.col_int_key = `<subquery2>`.col_int_key)
12723+
-> Table scan on t4
1272512724

1272612725
SELECT *
1272712726
FROM t4

mysql-test/r/warnings.result

+1
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ ERROR 23000: Duplicate entry '11' for key 'a'
339339
SHOW WARNINGS;
340340
Level Code Message
341341
Error 1062 Duplicate entry '11' for key 'a'
342+
Error 1028 Sort aborted: Duplicate entry '11' for key 'a'
342343

343344
DROP TABLE t1;
344345
DROP FUNCTION f1;

mysql-test/r/window_functions_explain.result

+3-6
Original file line numberDiff line numberDiff line change
@@ -16758,8 +16758,7 @@ SELECT ROW_NUMBER() OVER (PARTITION BY i), SUM(i) OVER (ORDER BY i DESC) FROM t
1675816758
"num_initial_chunks_spilled_to_disk": 0,
1675916759
"peak_memory_used": "NNN",
1676016760
"sort_algorithm": "std::stable_sort",
16761-
"unpacked_addon_fields": "using_heap_table",
16762-
"sort_mode": "<fixed_sort_key, rowid>"
16761+
"sort_mode": "<fixed_sort_key, packed_additional_fields>"
1676316762
}
1676416763
},
1676516764
{
@@ -16803,8 +16802,7 @@ SELECT ROW_NUMBER() OVER (PARTITION BY i), SUM(i) OVER (ORDER BY i DESC) FROM t
1680316802
"num_initial_chunks_spilled_to_disk": 0,
1680416803
"peak_memory_used": "NNN",
1680516804
"sort_algorithm": "std::stable_sort",
16806-
"unpacked_addon_fields": "using_heap_table",
16807-
"sort_mode": "<fixed_sort_key, rowid>"
16805+
"sort_mode": "<fixed_sort_key, packed_additional_fields>"
1680816806
}
1680916807
},
1681016808
{
@@ -16848,8 +16846,7 @@ SELECT ROW_NUMBER() OVER (PARTITION BY i), SUM(i) OVER (ORDER BY i DESC) FROM t
1684816846
"num_initial_chunks_spilled_to_disk": 0,
1684916847
"peak_memory_used": "NNN",
1685016848
"sort_algorithm": "std::sort",
16851-
"unpacked_addon_fields": "using_heap_table",
16852-
"sort_mode": "<fixed_sort_key, rowid>"
16849+
"sort_mode": "<fixed_sort_key, packed_additional_fields>"
1685316850
}
1685416851
}
1685516852
]

mysql-test/r/with_recursive.result

+2-2
Original file line numberDiff line numberDiff line change
@@ -2573,7 +2573,7 @@ sum(n)
25732573
5050
25742574
show status like 'Created_tmp_disk_tables';
25752575
Variable_name Value
2576-
Created_tmp_disk_tables 54
2576+
Created_tmp_disk_tables 53
25772577
# Too long key (>3000 bytes in latin1)
25782578
with recursive cte as
25792579
(
@@ -2627,4 +2627,4 @@ Note 1003 with recursive `qn` as (/* select#2 */ select 1 AS `a` from `test`.`t1
26272627
drop table t1;
26282628
show status like 'Created_tmp_disk_tables';
26292629
Variable_name Value
2630-
Created_tmp_disk_tables 59
2630+
Created_tmp_disk_tables 58

0 commit comments

Comments
 (0)