Eleytherios Stamatogiannakis wrote:
> My understanding (and what my experiments have shown) is that in both
> cases "COMPOUND SUBQUERIES 1 AND 2" will write a temp file to /var/tmp.

Okay, let's create a test database ...

  $ strace -e trace=open sqlite3 test.db
  [...]
  sqlite> create table t(x);
  open("/tmp/test.db-journal", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 4
  open("/dev/urandom", O_RDONLY|O_CLOEXEC) = 5
  open("/tmp", O_RDONLY|O_CLOEXEC)        = 5
  sqlite> begin;
  sqlite> insert into t values('looooooooooooooooong string');
  open("/tmp/test.db-journal", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 4
  sqlite> insert into t select * from t;
  sqlite> insert into t select * from t;
  sqlite> insert into t select * from t;

... that becomes so big that the subquery overflows the cache:

  [...]
  sqlite> insert into t select * from t;
  open("/var/tmp/etilqs_Oekg82a6826YGdz", 
O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0600) = 5
  sqlite> commit;

Only the UNION query claims to use temporary storage for the subquery:
(These two queries are constructed so that they have no result records.)

  sqlite> explain query plan select * from (select rowid, x from t union all 
select rowid, x from t) where x = '';
  1|0|0|SCAN TABLE t (~100000 rows)
  2|0|0|SCAN TABLE t (~100000 rows)
  0|0|0|COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)
  sqlite> explain query plan select * from (select rowid, x from t union select 
rowid, x from t) where x = '';
  2|0|0|SCAN TABLE t (~1000000 rows)
  3|0|0|SCAN TABLE t (~1000000 rows)
  1|0|0|COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)
  0|0|0|SCAN SUBQUERY 1 (~200000 rows)

When executing them, only UNION uses temporary files:

  sqlite> select * from (select rowid, x from t union all select rowid, x from 
t) where x = '';
  sqlite> select * from (select rowid, x from t union select rowid, x from t) 
where x = '';
  open("/var/tmp/etilqs_QNvTpzSHSedfFFM", 
O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0600) = 4
  open("/var/tmp/etilqs_RiTrAL6vrIxpnOu", 
O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0600) = 5


Now, what UNION ALL query wants to use a temporary table?
I'd guess that SQLite needs to save the result for some other reasons.


Regards,
Clemens
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to