HIT邹老师数据库实验三资源-CSDN文库
两个元组的分布规律
SELECT COUNT(*) FROM Foo;
SELECT COUNT(*) FROM Foo WHERE id = 0;
SELECT COUNT(*) FROM Foo WHERE a = 0;
SELECT COUNT(*) FROM Foo WHERE b = 0;
SELECT COUNT(*) FROM Foo WHERE c = 0;
文件里已经建完了 导入文件会报错
CREATE INDEX idx_a_b_c ON FooIdx(a, b, c);
CREATE INDEX idx_b_c ON FooIdx(b, c);
CREATE INDEX idx_tag ON FooIdx(tag);
CREATE INDEX idx_tag4 ON FooIdx(tag(4)); --该索引可以在MySQL上创建,但⽆法在PostgreSQL上创建
查看索引
source 路径 执行更快
SELECT * FROM Foo WHERE b = 123 AND c = 23;
SELECT * FROM FooIdx WHERE b = 123 AND c = 23;
左边为为增加索引 右边是增加索引的查询时间
不是前缀比较 因为他得先寻找b的值 但是c是连续的同时b不一定是连续,所以索引可能失效。
EXPLAIN SELECT * FROM Foo WHERE b = 123;
EXPLAIN SELECT * FROM FooIdx WHERE b = 123;
EXPLAIN SELECT * FROM FooIdx WHERE c = 23; -- ⾮前缀
EXPLAIN SELECT * FROM Foo WHERE tag LIKE '00123%';
EXPLAIN SELECT * FROM FooIdx WHERE tag LIKE '00123%'; -- MySQL: 使⽤前缀索引; PostgreSQL:
使⽤顺序扫描
EXPLAIN SELECT * FROM Foo WHERE b BETWEEN 123 AND 234;
EXPLAIN SELECT * FROM FooIdx WHERE b BETWEEN 123 AND 134;
EXPLAIN SELECT * FROM FooIdx WHERE b = 123 AND c BETWEEN 23 AND 45;
-- 多属性索引键的限制
EXPLAIN SELECT * FROM FooIdx WHERE b = 123 AND c + 1 = 24; -- 不能与表达式进⾏⽐较
EXPLAIN SELECT * FROM FooIdx WHERE a = 1234 AND c = 34; -- MySQL: 不能跳过中间属性;
EXPLAIN SELECT * FROM FooIdx WHERE a = 1234 AND b BETWEEN 234 AND 345 AND c = 34; -- 特别神奇,需要查点资料
分析原因:理论上不能跳跃属性进行查询,a的选择度比较高,通过筛选之后得到的元组比较少,所以DBMS自动优化了
-- 覆盖索引
EXPLAIN SELECT c FROM FooIdx WHERE b = 123;
EXPLAIN SELECT a FROM FooIdx WHERE b = 123; -- ⽆法覆盖
EXPLAIN SELECT id FROM FooIdx WHERE b = 123;
只需要找到索引项之后不用再回去找CS-001了
覆盖索引使得函数返回不需要回表了。
查看是否索引覆盖的方法: 看extra 是否是using index
-- 索引合并
EXPLAIN SELECT * FROM FooIdx WHERE tag LIKE '001234%' OR b = 56; -- MySQL: 使⽤索引合并;
访问时tag真正是idx_tag和idx_b_c并集得到元组的地址 先排序后归并using where
-- ⾮聚簇索引
EXPLAIN SELECT * FROM FooIdx WHERE b BETWEEN 123 AND 134;
EXPLAIN SELECT * FROM FooIdx WHERE b BETWEEN 123 AND 234; -- MySQL: 范围过⼤,查询优化器没⽤索引; PostgreSQL: ⽤索引
-- 前缀索引
EXPLAIN SELECT * FROM FooIdx WHERE tag LIKE '00123%'; -- MySQL: 使⽤前缀索引; PostgreSQL:使⽤顺序扫描
EXPLAIN SELECT * FROM FooIdx WHERE tag LIKE '0012%'; -- MySQL: 使⽤前缀索引; PostgreSQL:使⽤顺序扫描