数据库机构的设计(选取最适用的字段属性):
- 能使用小字段类型,就尽量用小字段类型;如能用short,就不要用int;能使用数字类,就不要用字符串类型。
- 尽量把字段设置为NOTNULL,这样将在未来执行查询的时候,数据库不用去比较NULL值。
- char和varchar的使用:char是不可变字符类型,varchar是可变字符类型 。如果字符串的长度不确定的情况下–char查询快,但消耗内存空间。varchar查询慢,但节省空间。字段长度变化不大的情况下选择char,变化大的情况下选择varchar。
- 字段的长度在最大限度的满足可能需要的前提下,应该尽可能的设得短一些,这样就可以提高查询效率,而且在建立索引的时候也可以减少 资源的消耗。
查询优化:
保证在实现功能的基础上,尽量减少对数据库的访问次数;最小化结果集,从而减网络负担。
- 使用join来代替子查询:子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁,写起来也很容易。但是有些情况下JOIN将会使查询速度变得很快。因为在MySQL中使用JOIN将不需要在内存中创建临时表来完成逻辑上的查询工作。
- 使用索引查询应注意:
1.应尽量避免在where字句中对字段进行null值的判断,否则将会导致引擎放弃使用索引而进行全表扫描。
例:select id from table where num is null
可以给num的默认值赋值为0,确保num列中没有 null值,然后进行查询。
例:select id from table where num = 0
2.尽量避免 where 子句中使用 !=或< > 操作符,都则会使引擎放弃使用索引而进行全表扫描。优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。
3.尽量避免在 where 子句中使用 or 来连接条件,否则将会导致引擎放弃使用索引而进行全表扫描。
例:select id from table where num = 10 or num = 20
使用or将会进行全表扫描,使用union进行连接。
例:select id from table where num = 10 union all select id from table where num = 20
4.in 和 not in的使用,因为in会使用系统无法使用索引,而只能直接搜索表中的数据。
例:select id from table where num in(1,2,3)
对于连续的数值,能用between就不要使用in了
例:select id from table where num between 1 and 3
5.尽量避免在索引过的字符串数据中,使用非打头字母搜索。这使得引擎无法利用索引。
例:select * from table where name like '%L%'
索引将会失效。
应使用打头字母进行搜索,索引将不会失效:
例:select *from table where name like ''L%
6.应尽量避免where子句中对字段进行表达式操作,将会导致引擎放弃使用索引而进行全表扫描。
例:select *from table where F1/2 =100
应改为
select *from table where F1 = 100*2
7.应尽量避免在where子句中对字段进行函数操作,这将导致索引失效。任何对列的操作都将会导致表扫描,它包括数据库函数,计算表达式等等,查询时应尽可能的将操作移到“=”的右边。
8.在使用索引字段作为条件时,如果该索引为复合索引,那么必须使用到改索引中的第一个字段做为条件时才能保证系统使用到该索引(最左前缀索引),并且尽可能的让字段顺序与索引顺序相一致。
9.充分利用连接条件,在某种情况下,两个表之间可能不只一个连接条件,这时我咋where子句中将连接条件完整的写上,有可能大大提高查询速度。
10.临时表的使用,当需要重复引用大型表或常用表中的某个数据集时可以考虑建立临时表。如果使用了临时表,在存储过程的最后一定将所有的临时表进行删除,这样可以避免系统表的较长时间锁定。
事务
仅管很多处理都可以通过使用子查询,链接,联合进行操作,但是更多的时候是需要用到一系列的语句来完成某种工作。但是当这个语句块中的某一条语句运行出错的时候,整个语句块的操作就会变得不确定起来。要避免这种情况的发生,就应该使用事务,他的作用是:要么语句块中的每一条语句都操作成功,要么都失败。事务以BEGIN关键字开始,COMMIT关键字节数。在这之间的一条sql操作失败,那么,ROLLBACK命令就可以把数据库恢复到BEGIN开始之前的状态。
锁定表
仅管事务是维护数据库完整性的一个非常好的方法,但却因为他的独立性,有时会影响数据库的性能,尤其是在很大的应用系统中。由于在事务执行的过程中,数据库将会被锁定,因此其它的用户请求只能暂时等待直到事务结束。如果访问量小点的话影响也一般,但是用户数量增大时将会造成等待时间变长。 系统利用锁,保证数据的完整性。
建立合适的索引
创建索引一般有两个目的:维护被索引列的唯一性和提供款速访问表中数据的策略。
大型数据库有两种索引聚簇索引和非聚簇索引。非聚簇索引的表是按堆结构存储数据,所有的数据均添加在表的尾部,而聚簇索引的数据在物理上会按照簇索引键的顺序存储,一个表只允许有一个簇索引,数据与索引是放到一块的,找到索引也就找到了数据。
使用聚簇索引和非聚簇索引的场合:
动作 | 聚簇索引 | 非聚簇索引 |
---|---|---|
列经常被分组排序 | 是 | 是 |
返回某范围内的数据 | 是 | 否 |
小数目的不同值 | 是 | 否 |
大数目的不同值 | 否 | 是 |
频繁更新列 | 否 | 是 |
频繁修改索引列 | 否 | 是 |
我们可以通过前面聚集索引和非聚集索引的定义理解上表。如:返回某范围内的数据一项。比如表中有一个时间列,恰好把聚合索引建立在了该列,这时查询某一时间段的全部数据时,查询速度很快因为这本字典正文是按时间排序的,聚簇索引只需要找到要检索的所有数据中开头和结尾的数据即可;而不像非聚集索引,必须先找到目录中查到每一项数据对应的页码,然而再根据页码查到具体内容。