xref: /sqlite-3.40.0/test/analyzeG.test (revision 06c7cc76)
15c193464Sdan# 2020-02-23
25c193464Sdan#
35c193464Sdan# The author disclaims copyright to this source code.  In place of
45c193464Sdan# a legal notice, here is a blessing:
55c193464Sdan#
65c193464Sdan#    May you do good and not evil.
75c193464Sdan#    May you find forgiveness for yourself and forgive others.
85c193464Sdan#    May you share freely, never taking more than you give.
95c193464Sdan#
105c193464Sdan#***********************************************************************
115c193464Sdan# Tests for functionality related to ANALYZE.
125c193464Sdan#
135c193464Sdan
145c193464Sdanset testdir [file dirname $argv0]
155c193464Sdansource $testdir/tester.tcl
165c193464Sdan
1735d3cb80Sdrhifcapable !stat4 {
1835d3cb80Sdrh  finish_test
1935d3cb80Sdrh  return
2035d3cb80Sdrh}
215c193464Sdanset testprefix analyzeG
225c193464Sdan
235c193464Sdan#-------------------------------------------------------------------------
245c193464Sdan# Test cases 1.* seek to verify that even if an index is not used, its
255c193464Sdan# stat4 data may be used by the planner to estimate the number of
265c193464Sdan# rows that match an unindexed constraint on the same column.
275c193464Sdan#
285c193464Sdando_execsql_test 1.0 {
295c193464Sdan  PRAGMA automatic_index = 0;
305c193464Sdan  CREATE TABLE t1(a, x);
315c193464Sdan  CREATE TABLE t2(b, y);
325c193464Sdan  WITH s(i) AS (
335c193464Sdan    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
345c193464Sdan  )
355c193464Sdan  INSERT INTO t1 SELECT (i%50), NULL FROM s;
365c193464Sdan  WITH s(i) AS (
375c193464Sdan    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
385c193464Sdan  )
395c193464Sdan  INSERT INTO t2 SELECT (CASE WHEN i<95 THEN 44 ELSE i END), NULL FROM s;
405c193464Sdan}
415c193464Sdan
425c193464Sdan# Join tables t1 and t2. Both contain 100 rows. (a=44) matches 2 rows
435c193464Sdan# in "t1", (b=44) matches 95 rows in table "t2". But the planner doesn't
445c193464Sdan# know this, so it has no preference as to which order the tables are
455c193464Sdan# scanned in. In practice this means that tables are scanned in the order
465c193464Sdan# they are specified in in the FROM clause.
47*06c7cc76Sdrhdo_eqp_test 1.1.1 {
485c193464Sdan  SELECT * FROM t1, t2 WHERE a=44 AND b=44;
495c193464Sdan} {
50*06c7cc76Sdrh
515c193464Sdan}
52*06c7cc76Sdrhdo_eqp_test 1.1.2 {
535c193464Sdan  SELECT * FROM t2, t1 WHERE a=44 AND b=44
545c193464Sdan} {
55*06c7cc76Sdrh  QUERY PLAN
56*06c7cc76Sdrh  |--SCAN t2
57*06c7cc76Sdrh  `--SCAN t1
585c193464Sdan}
595c193464Sdan
605c193464Sdando_execsql_test 1.2 {
615c193464Sdan  CREATE INDEX t2b ON t2(b);
625c193464Sdan  ANALYZE;
635c193464Sdan}
645c193464Sdan
655c193464Sdan# Now, with the ANALYZE data, the planner knows that (b=44) matches a
665c193464Sdan# large number of rows. So it elects to scan table "t1" first, regardless
675c193464Sdan# of the order in which the tables are specified in the FROM clause.
68*06c7cc76Sdrhdo_eqp_test 1.3.1 {
695c193464Sdan  SELECT * FROM t1, t2 WHERE a=44 AND b=44;
705c193464Sdan} {
71*06c7cc76Sdrh  QUERY PLAN
72*06c7cc76Sdrh  |--SCAN t1
73*06c7cc76Sdrh  `--SCAN t2
745c193464Sdan}
75*06c7cc76Sdrhdo_eqp_test 1.3.2 {
765c193464Sdan  SELECT * FROM t2, t1 WHERE a=44 AND b=44
775c193464Sdan} {
78*06c7cc76Sdrh  QUERY PLAN
79*06c7cc76Sdrh  |--SCAN t1
80*06c7cc76Sdrh  `--SCAN t2
815c193464Sdan}
825c193464Sdan
835c193464Sdan
845c193464Sdanfinish_test
85