如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
MySQL性能优化全攻略(二)※索引表索引ttActualPCttAssignedPCttClientIDetEMPLOYID(主键)doCUSTNMBR(主键)※tt.ActualPC值分布不均匀在进行任何优化之前,EXPLAIN对SELECT执行分析的结果如下:tabletypepossible_keyskeykey_lenrefrowsExtraetALLPRIMARYNULLNULLNULL74doALLPRIMARYNULLNULLNULL2135et_1ALLPRIMARYNULLNULLNULL74ttALLAssignedPC,ClientID,ActualPCNULLNULLNULL3872rangecheckedforeachrecord(keymap:35)每一个表的type都是ALL,它表明MySQL为每一个表进行了完全连接!这个操作是相当耗时的,因为待处理行的数量达到每一个表行数的乘积!即,这里的总处理行数为74*2135*74*3872=45,268,558,720。这里的问题之一在于,如果数据库列的声明不同,MySQL(还)不能有效地运用列的索引。在这个问题上,VARCHAR和CHAR是一样的,除非它们声明的长度不同。由于tt.ActualPC声明为CHAR(10),而et.EMPLOYID声明为CHAR(15),因此这里存在列长度不匹配问题。为了解决这两个列的长度不匹配问题,用ALTERTABLE命令把ActualPC列从10个字符扩展到15字符,如下所示:mysql>ALTERTABLEttMODIFYActualPCVARCHAR(15);现在tt.ActualPC和et.EMPLOYID都是VARCHAR(15)了,执行EXPLAIN进行分析得到的结果如下所示:tabletypepossible_keyskeykey_lenrefrowsExtrattALLAssignedPC,ClientID,ActualPCNULLNULLNULL3872whereused1doALLPRIMARYNULLNULLNULL2135rangecheckedforeachrecord(keymap:1)et_1ALLPRIMARYNULLNULLNULL74rangecheckedforeachrecord(keymap:1)eteq_refPRIMARYPRIMARY15tt.ActualPC1这还算不上完美,但已经好多了(行数的乘积现在少了一个系数74)。现在这个SQL命令执行大概需要数秒钟时间。为了避免tt.AssignedPC=et_1.EMPLOYID以及tt.ClientID=do.CUSTNMBR比较中的列长度不匹配,我们可以进行如下改动:mysql>ALTERTABLEttMODIFYAssignedPCVARCHAR(15),MODIFYClientIDVARCHAR(15);现在EXPLAIN显示的结果如下:tabletypepossible_keyskeykey_lenrefrowsExtraetALLPRIMARYNULLNULLNULL74ttrefAssignedPC,ClientID,ActualPCActualPC15et.EMPLOYID52whereusedet_1eq_refPRIMARYPRIMARY15tt.AssignedPC1doeq_refPRIMARYPRIMARY15tt.ClientID1这个结果已经比较令人满意了。余下的问题在于,默认情况下,MySQL假定tt.ActualPC列的值均匀分布,而事实上tt表的情况并非如此。幸而,我们可以很容易地让MySQL知道这一点:shell>myisamchk--analyzePATH_TO_MYSQL_DATABASE/ttshell>mysqladminrefresh现在这个连接操作已经非常理想,EXPLAIN分析的结果如下:tabletypepossible_keyskeykey_lenrefrowsExtrattALLAssignedPC,ClientID,ActualPCNULLNULLNULL3872whereusedeteq_refPRIMARYPRIMARY15tt.ActualPC1et_1eq_refPRIMARYPRIMARY15tt.AssignedPC1doeq_refPRIMARYPRIMARY15tt.ClientID1▲OPTIMIZE2OPTIMIZE能够恢复和整理磁盘