数据库的多表大数据查询应如何优化?

数据库的多表大数据查询应如何优化?,第1张

1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:\x0d\x0aselect id from t where num is null\x0d\x0a可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:\x0d\x0aselect id from t where num=0\x0d\x0a2.应尽量避免在 where 子句中使用!=或 *** 作符,否则将引擎放弃使用索引而进行全表扫描。优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。\x0d\x0a3.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:\x0d\x0aselect id from t where num=10 or num=20\x0d\x0a可以这样查询:\x0d\x0aselect id from t where num=10\x0d\x0aunion all\x0d\x0aselect id from t where num=20\x0d\x0a4.in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据。如:\x0d\x0aselect id from t where num in(1,2,3)\x0d\x0a对于连续的数值,能用 between 就不要用 in 了:\x0d\x0aselect id from t where num between 1 and 3\x0d\x0a5.尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。 \x0d\x0a见如下例子: \x0d\x0aSELECT * FROM T1 WHERE NAME LIKE ‘%L%’ \x0d\x0aSELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’ \x0d\x0aSELECT * FROM T1 WHERE NAME LIKE ‘L%’ \x0d\x0a即使NAME字段建有索引,前两个查询依然无法利用索引完成加快 *** 作,引擎不得不对全表所有数据逐条 *** 作来完成任务。而第三个查询能够使用索引来加快 *** 作。\x0d\x0a6.必要时强制查询优化器使用某个索引,如在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:\x0d\x0aselect id from t where num=@num\x0d\x0a可以改为强制查询使用索引:\x0d\x0aselect id from t with(index(索引名)) where num=@num\x0d\x0a7.应尽量避免在 where 子句中对字段进行表达式 *** 作,这将导致引擎放弃使用索引而进行全表扫描。如:\x0d\x0aSELECT * FROM T1 WHERE F1/2=100 \x0d\x0a应改为: \x0d\x0aSELECT * FROM T1 WHERE F1=100*2\x0d\x0aSELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=’5378’ \x0d\x0a应改为: \x0d\x0aSELECT * FROM RECORD WHERE CARD_NO LIKE ‘5378%’\x0d\x0aSELECT member_number, first_name, last_name FROM members \x0d\x0aWHERE DATEDIFF(yy,datofbirth,GETDATE()) >21 \x0d\x0a应改为: \x0d\x0aSELECT member_number, first_name, last_name FROM members \x0d\x0aWHERE dateofbirth ='2005-11-30' and createdate0) \x0d\x0aSELECT SUM(T1.C1) FROM T1WHERE EXISTS( \x0d\x0aSELECT * FROM T2 WHERE T2.C2=T1.C2) \x0d\x0a两者产生相同的结果,但是后者的效率显然要高于前者。因为后者不会产生大量锁定的表扫描或是索引扫描。

MySQL 对于千万级的大表的优化:

常用的优化sql----突出快字,使完成 *** 作的时间最短

1、用索引提高效率:

2、选择有效率的表名顺序,及数据结构及字段;

3、使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表;

4、删除重复记;

5、过内部函数提高SQL效率;......

读写分离----- *** 作不在一个表里完成

1、主数据库A,进行事务性增、改、删 *** 作(INSERT、UPDATE、DELETE);

2、从数据库B,进行SELECT查询 *** 作;

3、A复制到B,使数据保持一致性;

垂直划分 ------数据不存储在一个服务器里

按照功能划分,把数据分别放到不同的数据库和服务器。如博客功能的放到服务器A,储存文件放到服务器B;

水平划分------相同数据结构的数据不放在一张表里

把一个表的数据根据一定的规则划分到不同的数据库,两个数据库的表结构一样。

数据归档处理-----时间优先原则存储读取

将数据库中不经常使用的数据迁移至近线设备,将长期不使用的数据迁移至文件形式归档。这样,随着应用的需要,数据会在在线、近线和文件文档之间移动,如当应用需要访问很久以前的某些数据,它们的物理位置在近线设备,则会自动移动到在线设备。对用户的应用而言,这些都是透明的,就像所有数据都存放在在线设备一样,不会对数据库应用产生任何影响。

可以采取两个手段: 

第一:将数据库表拆分到不同的库中,比如 tblMEMBER 就可以拆分到 DB1 与 DB2 中去。 实际上,可以拆分到 DB001 ... DB100 甚至更多的库中间去。 DB1 与 DB2 最好不在一块硬盘上。

第二:如果更大量级的数据,则最好拆分到不同的数据库服务器中去。 数据库的拆分带来的是查询等 *** 作的复杂性。简单地可以通过 hash 或者 按序号 匹配不同的数据库。复杂一些,应该设置一个独立的应用服务器(软件)协调其中的 *** 作。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9249554.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-26
下一篇2023-04-26

发表评论

登录后才能评论

评论列表(0条)

    保存