diff options
author | unknown <sergefp@mysql.com> | 2006-10-31 21:30:40 +0300 |
---|---|---|
committer | unknown <sergefp@mysql.com> | 2006-10-31 21:30:40 +0300 |
commit | 84526c67ea072c8d22b100a191049b5d7bffbda6 (patch) | |
tree | d758fb2ffd64314cda0cf5be44928c3fdf812b76 /sql/item_subselect.cc | |
parent | 48df3b96a1719141749c05e4080c57366e9d0fbe (diff) | |
download | mariadb-git-84526c67ea072c8d22b100a191049b5d7bffbda6.tar.gz |
BUG#8804: Better comment + TODO section with suggestion how to speedup
the fix.
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r-- | sql/item_subselect.cc | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 489a647402e..27cd376001e 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1946,11 +1946,44 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine() full_scan DESCRIPTION - Resolve subquery using index lookup(s). - First look for specified constant, - If not found and we need to check for NULLs, do that too. + The engine is used to resolve subqueries in form + + oe IN (SELECT key FROM tbl WHERE subq_where) + + The value of the predicate is calculated as follows: + 1. If oe IS NULL, this is a special case, do a full table scan on + table tbl and search for row that satisfies subq_where. If such + row is found, return NULL, otherwise return FALSE. + 2. Make an index lookup via key=oe, search for a row that satisfies + subq_where. If found, return TRUE. + 3. If check_null==TRUE, make another lookup via key=NULL, search for a + row that satisfies subq_where. If found, return NULL, otherwise + return FALSE. + + TODO + The step #1 can be optimized further when the index has several key + parts. Consider a subquery: + + (oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where) + + and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}. + Current code will do a full table scan and obtain correct result. There + is a better option: instead of evaluating + + SELECT keypart1, keypart2 FROM tbl WHERE subq_where (1) + + and checking if it has produced any matching rows, evaluate + + SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1 (2) + + If this query produces a row, the result is NULL (as we're evaluating + "(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN, + i.e. NULL). If the query produces no rows, the result is FALSE. - NULL IN (SELECT ...) is a special case. + We currently evaluate (1) by doing a full table scan. (2) can be + evaluated by doing a "ref" scan on "keypart1=const1", which can be much + cheaper. We can use index statistics to quickly check whether "ref" scan + will be cheaper than full table scan. RETURN 0 |