有助于效率的类型选择
使你的数据尽可能小
最基本的优化之一是使你的数据(和索引)在磁盘上(并且在内存中)占据的空间尽可能小这能给出巨大的改进因为磁盘读入较快并且通常也用较少的主存储器如果在更小的列上做索引索引也占据较少的资源
你能用下面的技术使表的性能更好并且使存储空间最小
·尽可能地使用最有效(最小)的类型MySQL有很多节省磁盘空间和内存的专业化类型
·如果可能使表更小使用较小的整数类型例如MEDIUMINT经常比INT好一些
·如果可能声明列为NOT NULL它使任何事情更快而且你为每列节省一位注意如果在你的应用程序中你确实需要NULL你应该毫无疑问使用它只是避免缺省地在所有列上有它
使用定长列不使用可变长列
这条准则对被经常修改从而容易产生碎片的表来说特别重要例如应该选择 CHAR 列而不选择 VARCHAR 列所要权衡的是使用定长列时表所占用的空间更多但如果能够承担这种空间的耗费使用定长行将比使用可变长的行处理快得多
将列定义为 NOT NULL
这样处理更快所需空间更少而且有时还能简化查询因为不需要检查是否存在特例 NULL
考虑使用 ENUM 列
如果有一个只含有限数目的特定值的列那么应该考虑将其转换为 ENUM 列ENUM 列的值可以更快地处理因为它们在内部是以数值表示的
有关BLOB和TEXT类型
使用BLOB和TEXT类型的优点
用 BLOB 存储应用程序中包装或未包装的数据有可能使原来需要几个检索操作才能完成的数据检索得以在单个检索操作中完成而且还对存储标准表结构不易表示的数据或随时间变化的数据有帮助
使用BLOB和TEXT类型的可能弊端
另一方面BLOB 值也有自己的固有问题特别是在进行大量的 DELETE 或 UPDATE 操作时更是如此删除 BLOB 会在表中留下一个大空白在以后将需用一个记录或可能是不同大小的多个记录来填充
除非有必要否则应避免检索较大的 BLOB 或 TEXT 值例如除非肯定WHERE 子句能够将结果恰好限制在所想要的行上否则 SELECT * 查询不是一个好办法这样做可能会将非常大的 BLOB 值无目的地从网络上拖过来这是存储在另一列中的 BLOB 标识信息很有用的另一种情形可以搜索该列以确定想要的行然后从限定的行中检索 BLOB 值
必要的准则
对容易产生碎片的表使用 OPTIMIZE TABLE
大量进行修改的表特别是那些含有可变长列的表容易产生碎片碎片不好因为它在存储表的磁盘块中产生不使用的空间随着时间的增长必须读取更多的块才能取到有效的行从而降低了性能任意具有可变长行的表都存在这个问题但这个问题对 BLOB 列更为突出因为它们尺寸的变化非常大经常使用 OPTIMIZE TABLE 有助于保持性能不下降
使用多列索引
多列索引列有时很有用一种技术是根据其他列建立一个散列值并将其存储在一个独立的列中然后可通过搜索散列值找到行这只对精确匹配的查询有效(散列值对具有诸如<或>=这样的操作符的范围搜索没有用处)在MySQL 版及以上版本中散列值可利用 MD( ) 函数产生散列索引对 BLOB 列特别有用有一事要注意在 MySQL 以前的版本中不能索引 BLOB 类型甚至是在 或更新的版本中利用散列值作为标识值来查找 BLOB 值也比搜索 BLOB 列本身更快
将 BLOB 值隔离在一个独立的表中
在某些情况下将 BLOB 列从表中移出放入另一个副表可能具有一定的意义条件是移出 BLOB 列后可将表转换为定长行格式这样会减少主表中的碎片而且能利用定长行的性能优势
使用ANALYSE过程检查表列
如果使用的是 MySQL 或更新的版本应该执行 PROCEDURE ANALYSE( )查看它所提供的关于表中列的信息
ANALYSE([max elements[max memory]])
它检验来自你的查询的结果并返回结果的分析
max elements(缺省)是analyse将注意的每列不同值的最大数量这被ANALYSE用来检查最佳的列类型是否应该是ENUM类型
max memory(缺省)是在analyse尝试寻找所有不同值的时候应该分配给每列的最大内存量
SELECT FROM WHERE PROCEDURE ANALYSE([max elements[max memory]])
例如
mysql>SELECT * FROM student PROCEDURE ANALYSE();
mysql>SELECT * FROM student PROCEDURE ANALYSE();
相应输出中有一列是关于表中每列的最佳列类型的建议第二个例子要求 PROCEDURE ANALYSE( ) 不要建议含有多于 个值或取多于 字节的 ENUM 类型(可根据需要更改这些值)如果没有这样的限制输出可能会很长;ENUM 的定义也会很难阅读
根据 PROCEDURE ANALYSE( ) 的输出会发现可以对表进行更改以利用更有效的类型如果希望更改值类型使用 ALTER TABLE 语句即可