summaryrefslogtreecommitdiff
path: root/sql/item_subselect.cc
diff options
context:
space:
mode:
authorunknown <sergefp@mysql.com>2006-10-31 21:30:40 +0300
committerunknown <sergefp@mysql.com>2006-10-31 21:30:40 +0300
commit84526c67ea072c8d22b100a191049b5d7bffbda6 (patch)
treed758fb2ffd64314cda0cf5be44928c3fdf812b76 /sql/item_subselect.cc
parent48df3b96a1719141749c05e4080c57366e9d0fbe (diff)
downloadmariadb-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.cc41
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