In a database search of tens of millions, how to improve the query efficiency?

1. Database design: 

A. For query optimization, full table scan should be avoided as much as possible, and indexes should be established on the columns involved in where and order by first.

B. Try to avoid the null value judgment of the field in the where clause, otherwise the engine will give up the use of the index and perform a full table scan, such as:

select id from t where num is null

You can set a default value of 0 on num, make sure there are no null values ​​in the num column in the table, and then query like this:

select id from t where num=0

C. Not all indexes are valid for queries. SQL optimizes queries based on the data in the table. When a large amount of data in the index column is repeated, the query may not use the index. For example, there are fields sex, male, female in a table. Almost half, so even if an index is built on sex, it will not affect the query efficiency.

D. The more indexes the better, the index can certainly improve the efficiency of the corresponding select, but it also reduces the efficiency of insert and update, because the index may be rebuilt during insert or update, so how to build an index needs to be carefully considered. As the case may be. The number of indexes in a table should not exceed 6. If there are too many indexes, you should consider whether it is necessary to build indexes on some infrequently used columns.

E. Update index data columns should be avoided as much as possible, because the order of index data columns is the physical storage order of table records. Once the value of this column changes, the order of the entire table records will be adjusted, which will consume considerable resources. If the application system needs to update the index data column frequently, it needs to consider whether the index should be built as an index.

F. Try to use numeric fields as much as possible. If the fields only contain numeric information, try not to design them as character fields, which will reduce the performance of query and connection and increase the storage overhead. This is because the engine compares each character of the string one by one when processing queries and joins, whereas only one comparison is required for numbers.

G. Use varchar/nvarchar instead of char/nchar as much as possible, because the storage space of variable-length fields is small, which can save storage space, and secondly, for queries, the search efficiency in a relatively small field is obviously higher.

H. 尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

I. 避免频繁创建和删除临时表,以减少系统表资源的消耗。

J. 临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。

K. 在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

L. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

2、SQL语句方面:

A. 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

B. 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:

select id from t where num=10 or num=20

可以这样查询:

select id from t where num=10 union all select id from t where num=20

C. in 和 not in 也要慎用,否则会导致全表扫描,如:

select id from t where num in(1,2,3)

对于连续的数值,能用 between 就不要用 in 了:

select id from t where num between 1 and 3

D. 下面的查询也将导致全表扫描:

select id from t where name like ‘%abc%’

E. 如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:

select id from t where num=@num

可以改为强制查询使用索引:

select id from t with(index(索引名)) where num=@num

F. 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select id from t where num/2=100

应改为:

select id from t where num=100*2

G. 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select id from t where substring(name,1,3)=’abc’
–name以abc开头的id 
select id from t where datediff(day,createdate,’2005-11-30′)=0–‘2005-11-30’
生成的id 应改为: 
select id from t where name like ‘abc%’ select id from t where
createdate>=’2005-11-30′ and createdate<’2005-12-1′

H. 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

I. 不要写一些没有意义的查询,如需要生成一个空表结构:

select col1,col2 into #t from t where 1=0

这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样: create table #t(…)

J. 很多时候用 exists 代替 in 是一个好的选择:

select num from a where num in(select num from b)

用下面的语句替换:

select num from a where exists(select 1 from b where num=a.num)

K. 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

L. 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

M. 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

N. 尽量避免大事务操作,提高系统并发能力。

O、当只要一行数据时使用LIMIT 1;

当你查询表的有些时候,你已经知道结果只会有一条结果,单因为你可能需要去fetch游标,或是你也许会去检查返回的记录数。
在这种情况下,加上LIMIT 1 可以增加性能。这样一样, MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查找下一条符合记录的数据。

P、千万不要ORDER BY RAND();

Q、避免SELECT *;

R、使用 ENUM 而不是 VARCHAR ?

ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。

如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。

S、把IP地址存成 UNSIGNED INT

很多程序员都会创建一个 VARCHAR(15) 字段来存放字符串形式的IP而不是整形的IP。如果你用整形来存放,只需要4个字节,并且你可以有定长的字段。而且,这会为你带来查询上的优势,尤其是当你需要使用这样的WHERE条件:IP between ip1 and ip2。

我们必需要使用UNSIGNED INT,因为 IP地址会使用整个32位的无符号整形

3、Java方面:重点内容

A.尽可能的少造对象。

B.合理摆正系统设计的位置。大量数据操作,和少量数据操作一定是分开的。大量的数据操作,肯定不是ORM框架搞定的。,

C.使用jDBC链接数据库操作数据

D.控制好内存,让数据流起来,而不是全部读到内存再处理,而是边读取边处理;

E.合理利用内存,有的数据要缓存


如何优化数据库,如何提高数据库的性能?

解答:

1) 硬件调整性能 最有可能影响性能的是磁盘和网络吞吐量,解决办法扩大虚拟内存,并保证有足够可以扩充的空间;把数据库服务器上的不必要服务关闭掉;把数据库服务器和主域服务器分开;把SQL数据库服务器的吞吐量调为最大;在具有一个以上处理器的机器上运行SQL。

2)调整数据库

若对该表的查询频率比较高,则建立索引;建立索引时,想尽对该表的所有查询搜索操作, 按照where选择条件建立索引,尽量为整型键建立为有且只有一个簇集索引,数据在物理上按顺序在数据页上,缩短查找范围,为在查询经常使用的全部列建立非簇集索引,能最大地覆盖查询;但是索引不可太多,执行UPDATE DELETE INSERT语句需要用于维护这些索引的开销量急剧增加;避免在索引中有太多的索引键;避免使用大型数据类型的列为索引;保证每个索引键值有少数行。

3)使用存储过程

应用程序的实现过程中,能够采用存储过程实现的对数据库的操作尽量通过存储过程来实现,因为存储过程是存放在数据库服务器上的一次性被设计、编码、测试,并被再次使用,需要执行该任务的应用可以简单地执行存储过程,并且只返回结果集或者数值,这样不仅可以使程序模块化,同时提高响应速度,减少网络流量,并且通过输入参数接受输入,使得在应用中完成逻辑的一致性实现。

4)应用程序结构和算法

建立查询条件索引仅仅是提高速度的前提条件,响应速度的提高还依赖于对索引的使用。因为人们在

使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,特别是对数据量不是特别大的数据库操作时,是否建立索引和使用索引的好坏对程序的响应速度并不大,因此程序员在书写程序时就忽略了不同的实现方法之间可能存在的性能差异,这种性能差异在数据量特别大时或者大型的或是复杂的数据库环境中(如联机事务处理OLTP或决策支持系统DSS)中表现得尤为明显。在工作实践中发现,不良的SQL往往来自于不恰当的索引设计、不充份的连接条件和不可优化的where子句。在对它们进行适当的优化后,其运行速度有了明显地提高!

 

http://www.techug.com/database-query-optimization

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326588110&siteId=291194637