mysql梳理了一些常识,先记录

1. 查询缓存(相同的查询执行多次的时候,查询结果会被缓存)
// 查询缓存不开启 
$r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()"); 


// 开启查询缓存 
$today = date("Y-m-d"); 
$r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'"); 




2. 明知只会有一条结果时,使用Limit 1, 查询会提前终止




3. 使用索引(后面细说)


4. 避免select * (后面解释)


5. 设置一个唯一ID,即使你可能不用


6. 根据情况是用""与NULL, 然后大部分情况请保持字段NOT NULL


7. 游标的使用


8. 小的,固定的自然就快(垂直划分,使用int,避免varchar,text等)


9. delete,insert量大需要拆分,避免长时间锁表
   while 1:
      effect_row = db.execute(delete from act where f_date < '2009' limit 1000)
      if effect_row == 0: break
      sleep(0.001)


10. 如果可以,用 GROUP BY 代替 DISTINCT




MySQL查询优化器:
1. 最主要的:尽可能的使用索引,并且利用索引排除尽可能多的行
2. 其次匹配数据行


EXPLAIN详解:
  id: 值越大,优先级越高
  select_type:
       simple: 简单select 无子查询, 无union
       PRIMARY: 
       UNION:
       DEPENDENT UNION:
       SUBQUERY
       DEPENDENT SUBQUERY:
       DERIVED: 




WHERE category_id = 1 AND comments > 1 ORDER BY views DESC
联合索引:ALTER TABLE `article` ADD INDEX x ( `category_id` , `comments`, `views` );
views 的排序会利用不到顺序,因为comments是一个范围(range), 办法: comments不加联合索引即可
B+Tree解释索引顺序问题(最左前缀原理与相关优化)


单一索引与联合索引区别


不该建立索引: 低选择性,如性别,地区等
如果某个字段几乎没有重复,则就是高选择性,使用B+树索引是最合适的.


select count(distinct(sex))/count(*) as Selectivity from f_user


其值在(0,1]
接近1则说明适合
Selectivity(选择性) 


B-Tree(B+Tree)定义:树高h, 度d, 各个节点有序(二分查找需有序)
    所有的叶子节点的深度等于树高h, 也就是说,所有叶子节点在树的同一层(下面说到的相邻叶子节点可直接遍历)


为什么要用B+Tree做为索引:
1. I/O复杂度
a. 磁盘最小的存储单位为页(page 一般为4K), B+Tree的一个节点直接申请一个页大小存储空间
linux获取系统页大小: tune2fs -l /dev/vda1 | grep "Block size" 


b. 根据预读原理, 缺页加载会同时加载附近几个页(页是对齐的)
c. 复杂度: O(h) = O(d为底N的对数), h一般为不超过三, 一次检索最多h-1次缺页异常(根节点常驻内存)
d. 磁盘平均读写速度在(7200 r/min): 1/(7200/60)/2 = 4.17ms, 外加寻道时间, 约为: 8ms上下


2. 内存检索复杂度: O(d为底N的对数), 耗时基本忽略不计
3. 根据B+Tree树特性, d越大则性能越好,同时又根据存储原理,d的最大值为:
dmax = floor(pagesize / (keysize + pointsize))
pagesize: 4kb
keysize: 主索引一般为自增int,4 bytes
pointsize: 位int, 4 bytes
则 dmax = floor( 4 * 1024 / 8 ) = 512
如果N为1千万 则I/0复杂度为: 512为底的1000万的对数 < 3


索引查找示例:http://www.cnblogs.com/wuchanming/p/6886020.html


4. InnoDB索引:
1. 主索引同时也是数据文件
因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),
如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,
如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形
2. 叶子节点包含完整的数据(聚集索引, MyISAM是非聚集索引, 叶子节点只有数据地址)
3. 
4. t_user表索引分析:
SELECT * FROM information_schema.tables WHERE  table_schema='wap_app' AND table_name = 't_user'
rows: 4221293 (4百万)
avg_row_length: 332(B+Tree叶子节点之间存储数据,一个节点可存储 4kb/332 bytes = )
data_length: 1401946112 (约1G)
index_length: 1643036672


6.  索引优化策略及最左匹配原则:
     







你可能感兴趣的:(mysql)