首页

/

归档

/

友链

/

独立黑客

/

关于


数据库索引设计与优化

这是读完了 <高性能MySQL> , <数据库索引设计与优化> 和 MySQL Manual 之后的总结。本文的所有知识都是与MySQL相关的,其他 数据库也许有不同。

mysql jiajun@127.0.0.1:fd_test> EXPLAIN SELECT * FROM user WHERE mobile='12345678910' OR fullname='小白';
+------+---------------+---------+-------------+---------------------+---------------------+-----------+--------+--------+-----------------------------------------------+
| id   | select_type   | table   | type        | possible_keys       | key                 | key_len   | ref    | rows   | Extra                                         |
|------+---------------+---------+-------------+---------------------+---------------------+-----------+--------+--------+-----------------------------------------------|
| 1    | SIMPLE        | user    | index_merge | MOBILE_IDX,IDX_NAME | MOBILE_IDX,IDX_NAME | 767,768   | <null> | 2      | Using union(MOBILE_IDX,IDX_NAME); Using where |
+------+---------------+---------+-------------+---------------------+---------------------+-----------+--------+--------+-----------------------------------------------+
1 row in set
Time: 0.010s

诸如AND, OR等语句,MySQL可能会使用多个索引检索出结果,然后对多个结果进行AND,OR等操作。

符合三星的查询是最佳的查询,但是实际过程我们往往难以做到,例如如果使用了ORM,一般都没有可能拿到第三颗星。

另外为什么是最左匹配原则呢?因为比较索引的时候是从左往右比较。

def query():
    result = []

    for row_in_b in B:
        for row_in_a in A:
            if row_in_b.key1 == row_in_a.key1:
                result.append(row_in_a)

    return result

这样的代码,如果在连表的字段上有索引,那么可能会生成:

def query():
    result = []

    for row_in_b in B:
        if row_in_b.key1 in A.key1:
            row_in_a = [i for i in A where A.key1 = row_in_b.key1]
            result.extend(row_in_a)

    return result

从而把时间复杂度从 O(n^2) 降低到 O(n lgn)

还有很多。。。不过不想写了。。。还是看书吧,哈哈哈