Slow window query execution introduced in 3.41.2
(1) By MichalCermak on 2023-07-28 14:20:24 [source]
Hi SQLite community, I recently updated SQLite and in version 3.41.2, I am getting much slower execution for a specific query containing a window function: WITH T(Id, ContId) AS(SELECT ROWID, row_number() OVER(ORDER BY ID) -1 FROM TestTable) UPDATE TestTable SET ContId=(SELECT ContId FROM T WHERE TestTable.ROWID=T.Id) The point of this query is to add a monotonic sequence (ContId) to the sorted Id column. When I executed EXPLAIN QUERY PLAN with the older version (3.41.1), I got this: id parent notused detail 4 0 0 SCAN TestTable 9 0 0 CORRELATED SCALAR SUBQUERY 2 12 9 0 CO-ROUTINE T 15 12 0 CO-ROUTINE (subquery-3) 18 15 0 SCAN TestTable 25 15 0 USE TEMP B-TREE FOR ORDER BY 39 12 0 SCAN (subquery-3) 89 9 0 SEARCH T USING AUTOMATIC COVERING INDEX (Id=?) Version 3.41.2 gives me a different result: id parent notused detail 4 0 0 SCAN TestTable 14 0 0 CORRELATED SCALAR SUBQUERY 2 17 14 0 CO-ROUTINE T 20 17 0 CO-ROUTINE (subquery-3) 23 20 0 SCAN TestTable USING COVERING INDEX Index 35 17 0 SCAN (subquery-3) 73 14 0 SCAN T I generated a random table with 10000 rows. In version 3.41.1 it was executed in 42ms, In version 3.41.2 it takes 19971ms. Thanks, Michal
(2) By Richard Hipp (drh) on 2023-07-28 14:26:51 in reply to 1 [link] [source]
Here is what you need to do:
Retest using the latest release: 3.42.0. Even better is to also try on the latest (unreleased) trunk version and/or on the latest pre-release snapshot.
If the problem has not yet been resolved, then provide us with a test case that we can run. Your test case should include the input database (or a script to generate the input database if the database is large) and a script to run in the SQLite CLI that gives poor performance.
(3) By MichalCermak on 2023-07-30 13:06:53 in reply to 2 [link] [source]
Retested with 3.42.0 and pre-release package, the issue is still present. Here is a git repo with simple Windows batch file showing the issue: https://github.com/MichalCermak123/slow_sqlite_window_function When I run it, I got this: c:\slow_sqlite_window_function>run.bat c:\slow_sqlite_window_function>set QUERY=WITH T(Id, ContId) AS(SELECT ROWID, row_number() OVER(ORDER BY ID) -1 FROM TestTable) UPDATE TestTable SET ContId=(SELECT ContId FROM T WHERE TestTable.ROWID=T.Id) c:\slow_sqlite_window_function>set QUERY_PLAN=EXPLAIN QUERY PLAN WITH T(Id, ContId) AS(SELECT ROWID, row_number() OVER(ORDER BY ID) -1 FROM TestTable) UPDATE TestTable SET ContId=(SELECT ContId FROM T WHERE TestTable.ROWID=T.Id) c:\slow_sqlite_window_function>copy /y test_db.db test_db_3410100.db 1 file(s) copied. c:\slow_sqlite_window_function>sqlite-tools-win32-x86-3410100\sqlite3.exe test_db_3410100.db "EXPLAIN QUERY PLAN WITH T(Id, ContId) AS(SELECT ROWID, row_number() OVER(ORDER BY ID) -1 FROM TestTable) UPDATE TestTable SET ContId=(SELECT ContId FROM T WHERE TestTable.ROWID=T.Id)" QUERY PLAN |--SCAN TestTable `--CORRELATED SCALAR SUBQUERY 2 |--CO-ROUTINE T | |--CO-ROUTINE (subquery-3) | | |--SCAN TestTable | | `--USE TEMP B-TREE FOR ORDER BY | `--SCAN (subquery-3) `--SEARCH T USING AUTOMATIC COVERING INDEX (Id=?) c:\slow_sqlite_window_function>echo Working (3410100) version start - 15:00:45.00 Working (3410100) version start - 15:00:45.00 c:\slow_sqlite_window_function>sqlite-tools-win32-x86-3410100\sqlite3.exe test_db_3410100.db -stats "WITH T(Id, ContId) AS(SELECT ROWID, row_number() OVER(ORDER BY ID) -1 FROM TestTable) UPDATE TestTable SET ContId=(SELECT ContId FROM T WHERE TestTable.ROWID=T.Id)" Memory Used: 2147944 (max 4482648) bytes Number of Outstanding Allocations: 688 (max 726) Number of Pcache Overflow Bytes: 2000008 (max 2092856) bytes Largest Allocation: 2048000 bytes Largest Pcache Allocation: 4256 bytes Lookaside Slots Used: 53 (max 123) Successful lookaside attempts: 20206 Lookaside failures due to size: 2 Lookaside failures due to OOM: 22 Pager Heap Usage: 2075864 bytes Page cache hits: 7 Page cache misses: 1057 Page cache writes: 528 Page cache spills: 90 Schema Heap Usage: 624 bytes Statement Heap/Lookaside Usage: 16352 bytes Fullscan Steps: 19998 Sort Operations: 1 Autoindex Inserts: 0 Bloom filter bypass taken: 0/10000 Virtual Machine Steps: 570038 Reprepare operations: 0 Number of times run: 1 Memory used by prepared stmt: 16352 c:\slow_sqlite_window_function>echo Working (3410100) version finish - 15:00:45.08 Working (3410100) version finish - 15:00:45.08 c:\slow_sqlite_window_function>copy /y test_db.db test_db_3410200.db 1 file(s) copied. c:\slow_sqlite_window_function>sqlite-tools-win32-x86-3410200\sqlite3.exe test_db_3410200.db "EXPLAIN QUERY PLAN WITH T(Id, ContId) AS(SELECT ROWID, row_number() OVER(ORDER BY ID) -1 FROM TestTable) UPDATE TestTable SET ContId=(SELECT ContId FROM T WHERE TestTable.ROWID=T.Id)" QUERY PLAN |--SCAN TestTable `--CORRELATED SCALAR SUBQUERY 2 |--CO-ROUTINE T | |--CO-ROUTINE (subquery-3) | | |--SCAN TestTable | | `--USE TEMP B-TREE FOR ORDER BY | `--SCAN (subquery-3) `--SCAN T c:\slow_sqlite_window_function>echo First slow (3410200) version start - 15:00:45.51 First slow (3410200) version start - 15:00:45.51 c:\slow_sqlite_window_function>sqlite-tools-win32-x86-3410200\sqlite3.exe test_db_3410200.db -stats "WITH T(Id, ContId) AS(SELECT ROWID, row_number() OVER(ORDER BY ID) -1 FROM TestTable) UPDATE TestTable SET ContId=(SELECT ContId FROM T WHERE TestTable.ROWID=T.Id)" Memory Used: 2151000 (max 4485488) bytes Number of Outstanding Allocations: 686 (max 713) Number of Pcache Overflow Bytes: 2003752 (max 2028352) bytes Largest Allocation: 2048000 bytes Largest Pcache Allocation: 4264 bytes Lookaside Slots Used: 54 (max 123) Successful lookaside attempts: 50035206 Lookaside failures due to size: 2 Lookaside failures due to OOM: 15 Pager Heap Usage: 2079776 bytes Page cache hits: 2582440 Page cache misses: 2718624 Page cache writes: 528 Page cache spills: 92 Schema Heap Usage: 624 bytes Statement Heap/Lookaside Usage: 15664 bytes Fullscan Steps: 99999999 Sort Operations: 10000 Autoindex Inserts: 0 Virtual Machine Steps: 1950575003 Reprepare operations: 0 Number of times run: 1 Memory used by prepared stmt: 15664 c:\slow_sqlite_window_function>echo First slow (3410200) version finish - 15:01:43.67 First slow (3410200) version finish - 15:01:43.67 c:\slow_sqlite_window_function>copy /y test_db.db test_db_3420000.db 1 file(s) copied. c:\slow_sqlite_window_function>sqlite-tools-win32-x86-3420000\sqlite3.exe test_db_3420000.db "EXPLAIN QUERY PLAN WITH T(Id, ContId) AS(SELECT ROWID, row_number() OVER(ORDER BY ID) -1 FROM TestTable) UPDATE TestTable SET ContId=(SELECT ContId FROM T WHERE TestTable.ROWID=T.Id)" QUERY PLAN |--SCAN TestTable `--CORRELATED SCALAR SUBQUERY 2 |--CO-ROUTINE T | |--CO-ROUTINE (subquery-3) | | |--SCAN TestTable | | `--USE TEMP B-TREE FOR ORDER BY | `--SCAN (subquery-3) `--SCAN T c:\slow_sqlite_window_function>echo Latest (3420000) version start - 15:01:43.76 Latest (3420000) version start - 15:01:43.76 c:\slow_sqlite_window_function>sqlite-tools-win32-x86-3420000\sqlite3.exe test_db_3420000.db -stats "WITH T(Id, ContId) AS(SELECT ROWID, row_number() OVER(ORDER BY ID) -1 FROM TestTable) UPDATE TestTable SET ContId=(SELECT ContId FROM T WHERE TestTable.ROWID=T.Id)" Memory Used: 2153192 (max 4487680) bytes Number of Outstanding Allocations: 677 (max 704) Number of Pcache Overflow Bytes: 2003752 (max 2028352) bytes Largest Allocation: 2048000 bytes Largest Pcache Allocation: 4264 bytes Lookaside Slots Used: 53 (max 123) Successful lookaside attempts: 50035208 Lookaside failures due to size: 2 Lookaside failures due to OOM: 10 Pager Heap Usage: 2079776 bytes Page cache hits: 2582440 Page cache misses: 2718624 Page cache writes: 528 Page cache spills: 92 Schema Heap Usage: 624 bytes Statement Heap/Lookaside Usage: 20416 bytes Fullscan Steps: 99999999 Sort Operations: 10000 Autoindex Inserts: 0 Virtual Machine Steps: 1950575003 Reprepare operations: 0 Number of times run: 1 Memory used by prepared stmt: 20416 c:\slow_sqlite_window_function>echo Latest (3420000) version finish - 15:02:42.00 Latest (3420000) version finish - 15:02:42.00 c:\slow_sqlite_window_function>sqlite-tools-win32-x86-3420000\sqldiff.exe test_db_3410100.db test_db_3410200.db c:\slow_sqlite_window_function>sqlite-tools-win32-x86-3420000\sqldiff.exe test_db_3410100.db test_db_3420000.db
(4.1) By Richard Hipp (drh) on 2023-07-31 11:35:28 edited from 4.0 in reply to 3 [link] [source]
The problem bisects to check-in 2c56b984a0bd3be5.
(5) By Richard Hipp (drh) on 2023-07-31 12:02:51 in reply to 3 [link] [source]
Simplified test script that runs in the CLI:
.echo on CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); CREATE TABLE t2(d INT); WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10000) INSERT INTO t1(a,b) SELECT x, x+1 FROM c; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000) INSERT INTO t2(d) SELECT x*2 FROM c; .timer on .eqp on WITH t3(x,y) AS (SELECT d, row_number()OVER() FROM t2) UPDATE t1 SET b=(SELECT y FROM t3 WHERE t1.a=t3.x);
Run in 0.02 seconds in 3.40.0 but takes about 4.0 seconds in 3.42.0.
(6) By Richard Hipp (drh) on 2023-08-01 13:02:38 in reply to 3 [link] [source]
Should now be fixed on trunk. The latest changes (including this fix) are in the pre-release snapshot tarball.