Sql优化or语句

合集下载

SQL优化-数据库SQL优化——使用EXIST代替IN

SQL优化-数据库SQL优化——使用EXIST代替IN

SQL优化-数据库SQL优化——使⽤EXIST代替IN1,查询进⾏优化,应尽量避免全表扫描对查询进⾏优化,应尽量避免全表扫描,⾸先应考虑在 where 及 order by 涉及的列上建⽴索引. 尝试下⾯的技巧以避免优化器错选了表扫描:· 使⽤ANALYZE TABLEtbl_name为扫描的表更新关键字分布。

· 对扫描的表使⽤FORCEINDEX告知,相对于使⽤给定的索引表扫描将⾮常耗时。

SELECT * FROM t1, t2 FORCE INDEX (index_for_column) WHERE t1.col_name=t2.col_name;· ⽤–max-seeks-for-key=1000选项启动mysqld或使⽤SET max_seeks_for_key=1000告知优化器假设关键字扫描不会超过1,000次关键字搜索。

1). 应尽量避免在 where ⼦句中对字段进⾏ null 值判断否则将导致引擎放弃使⽤索引⽽进⾏全表扫描,如:select id from t where num is nullNULL对于⼤多数数据库都需要特殊处理,MySQL也不例外,它需要更多的代码,更多的检查和特殊的索引逻辑,有些开发⼈员完全没有意识到,创建表时NULL是默认值,但⼤多数时候应该使⽤NOT NULL,或者使⽤⼀个特殊的值,如0,-1作为默不能⽤null作索引,任何包含null值的列都将不会被包含在索引中。

即使索引有多列这样的情况下,只要这些列中有⼀列含有null,该列就会从索引中排除。

也就是说如果某列存在空值,即使对该列建索引也不会提⾼性能。

任何在where⼦句中使⽤此例可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=02). 应尽量避免在 where ⼦句中使⽤!=或<>操作符否则将引擎放弃使⽤索引⽽进⾏全表扫描。

sql 组合条件查询语句

sql 组合条件查询语句

sql 组合条件查询语句组合条件查询语句是在SQL中使用多个条件来过滤所需的数据。

通常情况下,可以使用AND、OR和NOT等逻辑运算符来组合条件。

以下是一些示例:1. 使用AND组合条件:sql.SELECT FROM 表名。

WHERE 条件1 AND 条件2;例如:sql.SELECT FROM employees.WHERE department = 'IT' AND salary > 50000;2. 使用OR组合条件:sql.SELECT FROM 表名。

WHERE 条件1 OR 条件2;例如:sql.SELECT FROM products.WHERE category = 'Electronics' OR price > 1000;3. 使用NOT组合条件:sql.SELECT FROM 表名。

WHERE NOT 条件;例如:sql.SELECT FROM orders.WHERE NOT status = 'cancelled';4. 复杂条件组合:sql.SELECT FROM 表名。

WHERE (条件1 AND 条件2) OR (条件3 AND 条件4);例如:sql.SELECT FROM students.WHERE (age > 18 AND gender = 'Female') OR (grade = 'A' AND attendance > 90);在编写组合条件查询语句时,需要注意逻辑运算符的优先级,可以使用括号来明确指定条件的组合顺序,以确保查询结果符合预期。

希望以上示例能够帮助你理解如何在SQL中编写组合条件查询语句。

如果你有其他关于SQL查询的问题,欢迎继续提问。

NOTIN和OR的SQL语句优化

NOTIN和OR的SQL语句优化

NOTIN和OR的SQL语句优化
NOT IN 的优化:
例如:
select ID,name from Table_A where ID not in (select ID from Table_B)
这句是最经典的not in查询了。

改为表连接代码如下
将 NOT IN 改为表连接的⽅式进⾏优化
⽹上有篇帖⼦这样的
select
Table_A.ID,
Table_
from Table_A
left join Table_B on Table_A.ID=Table_B.ID and Table_B.ID is null
但是。

我试了不管⽤,条件没有过滤掉。

后来我把这个条件加在后边就可以了。

(可能是我SQL语句写错了?,反正以后我还是好⼏个地⽅都⽤的这种⽅式)select
Table_A.ID,
Table_
from Table_A
left join Table_B on Table_A.ID=Table_B.ID
where
Table_B.ID is null
其实我也感觉两种⽅式⼀样,但第⼀个我当时⽤的确实没过滤出来,(那已经是好⼏个表关联查询了)。

OR 的优化:
IN 和 OR 的优化⽐较相似
都采⽤关键字 UNION 的⽅式
将OR 的多个条件查分为多个查询后使⽤ UNION 连接为⼀个临时表就可以了。

顺带记录下 UNION ALL 和 UNION 的区别。

UNION ALL 将上下所有的数据拼到⼀块。

UNION 拼到⼀块后对数据进⾏过滤去重。

sql千万级数据量优化方案

sql千万级数据量优化方案

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=03.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num=10 or num=20可以这样查询:select id from t where num=10union allselect id from t where num=205.in 和 not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3)对于连续的数值,能用 between 就不要用 in 了:select id from t where num between 1 and 36.下面的查询也将导致全表扫描:select id from t where name like '%abc%'若要提高效率,可以考虑全文检索。

7.如果在 where 子句中使用参数,也会导致全表扫描。

因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。

然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。

如下面语句将进行全表扫描:select id from t where num=@num <mailto:num=@num>可以改为强制查询使用索引:select id from t with(index(索引名)) where num=@num <mailto:num=@num>8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。

sql注入攻击的常用方法

sql注入攻击的常用方法

sql注入攻击的常用方法
1. 通用注释:通过添加“--”到SQL查询中终止查询,导致可能被后台程序执行的SQL语句被自动终止,此时接受的是语句的注释版本,外界在查询中添加垃圾数据。

2. OR语句利用:在SQL语句中添加 OR 语句来绕过数据库的安全性控制,利用脚本修改现有规则或将数据返回值更改为真假。

3. 绕过双引号:通过添加“\”特殊字符对输入的内容进行转义,让应用不识别双引号;也就是进行双引号的覆盖,之后应用的参数存在未经过滤的漏洞,这样就可以用SQL进行投入攻击。

如:“select * from user where name\=\"admin\"”
4. 利用拖尾空格:恶意攻击者添加空格字符,让被注入的SQL语句能够正常执行,比如输入“' and1=1 ”,这样可以避免SQL解析器将单引号作为结尾进行解析。

5. 表达式匹配:恶意攻击者会使用正则表达式来拆分SQL代码,使用“%*”模糊查询来替换原始值,利用SQL语句中的操作运算符来添加恶意信息,如:%`' OR 1=1--`
6. 数据库指令:攻击者可以使用SQL语句中的union等指令,来将恶意代码和原始数据库里的信息进行拼接,一旦这种拼接成功后,数据库就可能会被恶意攻击者获取数据。

7. 特殊函数:还有一些特殊的字段,如系统函数,比如“ifnull”、“sleep”、“rand”等,可以让攻击者让被注入的数据库服务器延时执行以达到攻击数据库的目的。

8. 无尽苦读:用一些特殊字符来组合语句,以及多次尝试,来穷举出所有可能性。

oracle 的 SQL语句优化基本原则

oracle 的 SQL语句优化基本原则

一、操作符优化1、IN 操作符ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。

由此可见用IN的SQL至少多了一个转换的过程。

推荐方案:在业务密集的SQL当中尽量不采用IN操作符,用EXISTS 方案代替。

2、NOT IN操作符此操作是强列不推荐使用的,因为它不能应用表的索引。

推荐方案:用NOT EXISTS 方案代替3、IS NULL 或IS NOT NULL操作(判断字段是否为空)判断字段是否为空一般是不会应用索引的,因为索引是不索引空值的。

推荐方案:用其它相同功能的操作运算代替,如:a is not null 改为a>0 或a>”’’等。

4、> 及< 操作符(大于或小于操作符)大于或小于操作符一般情况下是不用调整的,因为它有索引就会采用索引查找,但有的情况下可以对它进行优化,如一个表有100万记录,一个数值型字段A,30万记录的A=0,30万记录的A=1,39万记录的A=2,1万记录的A=3。

那么执行A>2与A>=3的效果就有很大的区别了,因为A>2时ORACLE 会先找出为2的记录索引再进行比较,而A>=3时ORACLE则直接找到=3的记录索引。

5、LIKE操作符LIKE操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,如LIKE ‘%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。

一个实际例子:用YW_YHJBQK表中营业编号后面的户标识号可来查询营业编号YY_BH LIKE‘%5400%’ 这个条件会产生全表扫描,如果改成YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 则会利用YY_BH的索引进行两个范围的查询,性能肯定大大提高。

大数据量数据库设计与优化方案(SQL优化)

大数据量数据库设计与优化方案(SQL优化)

⼤数据量数据库设计与优化⽅案(SQL优化)⼀、数据库结构的设计如果不能设计⼀个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,⽽且将会影响系统实际运⾏的性能。

所以,在⼀个系统开始实施之前,完备的数据库模型的设计是必须的。

在⼀个系统分析、设计阶段,因为数据量较⼩,负荷较低。

我们往往只注意到功能的实现,⽽很难注意到性能的薄弱之处,等到系统投⼊实际运⾏⼀段时间后,才发现系统的性能在降低,这时再来考虑提⾼系统性能则要花费更多的⼈⼒物⼒,⽽整个系统也不可避免的形成了⼀个打补丁⼯程。

所以在考虑整个系统的流程的时候,我们必须要考虑,在⾼并发⼤数据量的访问情况下,我们的系统会不会出现极端的情况。

(例:对外统计系统在7⽉16⽇出现的数据异常的情况,并发⼤数据量的的访问造成,数据库的响应时间不能跟上数据刷新的速度造成。

具体情况是:在⽇期临界时(00:00:00),判断数据库中是否有当前⽇期的记录,没有则插⼊⼀条当前⽇期的记录。

在低并发访问的情况下,不会发⽣问题,但是当⽇期临界时的访问量相当⼤的时候,在做这⼀判断的时候,会出现多次条件成⽴,则数据库⾥会被插⼊多条当前⽇期的记录,从⽽造成数据错误),数据库的模型确定下来之后,我们有必要做⼀个系统内数据流向图,分析可能出现的瓶颈。

为了保证数据库的⼀致性和完整性,在逻辑设计的时候往往会设计过多的表间关联,尽可能的降低数据的冗余。

(例:⽤户表的地区,我们可以把地区另外存放到⼀个地区表中)如果数据冗余低,数据的完整性容易得到保证,提⾼了数据吞吐速度,保证了数据的完整性,清楚地表达数据元素之间的关系。

⽽对于多表之间的关联查询(尤其是⼤数据表)时,其性能将会降低,同时也提⾼了客户端程序的编程难度,因此,物理设计需折衷考虑,根据业务规则,确定对关联表的数据量⼤⼩、数据项的访问频度,对此类数据表频繁的关联查询应适当提⾼数据冗余设计但增加了表间连接查询的操作,也使得程序的变得复杂,为了提⾼系统的响应时间,合理的数据冗余也是必要的。

SQL语句优化--OR语句优化案例

SQL语句优化--OR语句优化案例

SQL语句优化--OR语句优化案例从上海来到温州,看了前⼏天监控的sql语句和数据变化,发现有⼀条语句的io次数很⼤,达到了150万次IO,⽽两个表的数据也就不到20万,为何有如此多的IO次数,下⾯是执⾏语句:select ws.nodeid,ststepid,wi.curstepid from Workflowinfo wi,Workflowstep ws where ws.workflowid='402881db1b441e6f011c0cff320e4766'and (ststepid = ws.id or (wi.curstepid = ws.id and isreceived=1and issubmited =1))执⾏IO统计结果如下:(22⾏受影响)表'workflowstep'。

扫描计数1,逻辑读取23次,物理读取0次,预读0次,lob 逻辑读取0次,lob 物理读取0次,lob 预读0次。

表'Worktable'。

扫描计数4,逻辑读取1490572次,物理读取0次,预读0次,lob 逻辑读取0次,lob 物理读取0次,lob 预读0次。

表'workflowinfo'。

扫描计数4,逻辑读取12208次,物理读取0次,预读0次,lob 逻辑读取0次,lob 物理读取0次,lob 预读0次。

表'Worktable'。

扫描计数0,逻辑读取0次,物理读取0次,预读0次,lob 逻辑读取0次,lob 物理读取0次,lob 预读0次。

执⾏计划如下:这⾥发现:主要是嵌套循环算法占的开销最⼤。

个⼈感觉是“Or”引起的性能问题,后来根据业务逻辑改写。

如下:语句修改如下:select ws.nodeid,ststepid,wi.curstepid from Workflowinfo wi, Workflowstep wswhere ws.workflowid='402881db1b441e6f011c0cff320e4766'and (ststepid = ws.id)union allselect ws.nodeid,ststepid,wi.curstepid from Workflowinfo wi, Workflowstep ws where ws.workflowid='402881db1b441e6f011c0cff320e4766'and (wi.curstepid = ws.id and isreceived=1查询IO次数如下:(22⾏受影响)表'workflowinfo'。

SQL优化的几种方法及总结

SQL优化的几种方法及总结

SQL优化的⼏种⽅法及总结优化⼤纲:通过explain 语句帮助选择更好的索引和写出更优化的查询语句。

SQL语句中的IN包含的值不应该过多。

当只需要⼀条数据的时候,使⽤limit 1。

如果限制条件中其他字段没有索引,尽量少⽤or。

尽量⽤union all代替union。

不使⽤ORDER BY RAND()。

区分in和exists、not in和not exists。

使⽤合理的分页⽅式以提⾼分页的效率。

查询的数据过⼤,可以考虑使⽤分段来进⾏查询。

避免在where⼦句中对字段进⾏null值判断。

避免在where⼦句中对字段进⾏表达式操作。

必要时可以使⽤force index来强制查询⾛某个索引。

注意查询范围,between、>、<等条件会造成后⾯的索引字段失效。

关于JOIN优化。

优化使⽤1、mysql explane ⽤法 explane显⽰了mysql如何使⽤索引来处理select语句以及连接表。

可以帮助更好的索引和写出更优化的查询语句。

EXPLAIN SELECT*FROM l_line WHERE `status` =1and create_at >'2019-04-11';explain字段列说明table:显⽰这⼀⾏的数据是关于哪张表的type:这是重要的列,显⽰连接使⽤了何种类型。

从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和allpossible_keys:显⽰可能应⽤在这张表中的索引。

如果为空,没有可能的索引。

可以为相关的域从where语句中选择⼀个合适的语句key:实际使⽤的索引。

如果为null,则没有使⽤索引。

很少的情况下,mysql会选择优化不⾜的索引。

这种情况下,可以在select语句中使⽤use index(indexname)来强制使⽤⼀个索引或者⽤ignore index(indexname)来强制mysql忽略索引key_len:使⽤的索引的长度。

mySql---or和in的效率问题(和=、=、between之间的关系)

mySql---or和in的效率问题(和=、=、between之间的关系)

mySql---or和in的效率问题(和=、=、between之间的关系)写在前⾯: 本⽂是直接拿取的别⼈的实验数据作参考,然后对数据作分析。

参考⽹友的测试数据结果:在⽹上⼀直看到的是or和in的效率没啥区别,⼀直也感觉是这样,前⼏天刚好在看《mysql数据库开发的36条军规》的⽂章,⾥⾯提到了or和in的效率问题,⽂中提到or的效率为O(n),⽽in的效率为O(log2n), 当n越⼤的时候效率相差越明显。

今天刚好有时间决定对⼼中的疑惑进⾏测试,下⾯是详细的测试过程。

第⼀步,创建测试表,并⽣成测试数据,测试数据为1000万条记录。

数据库版本为5.1.63。

数据库中关闭了query cache,因此数据库缓存不会对查询造成影响。

具体的代码如下:#创建测试的test表DROP TABLE IF EXISTS test;CREATE TABLE test(ID INT(10) NOT NULL,`Name` VARCHAR(20) DEFAULT '' NOT NULL,PRIMARY KEY( ID ))ENGINE=INNODB DEFAULT CHARSET utf8;#创建⽣成测试数据的存储过程DROP PROCEDURE IF EXISTS pre_test;DELIMITER //CREATE PROCEDURE pre_test()BEGINDECLARE i INT DEFAULT 0;SET autocommit = 0;WHILE i<10000000 DOINSERT INTO test ( ID,`Name` ) VALUES( i, CONCAT( 'Carl', i ) );SET i = i+1;IF i%2000 = 0 THENCOMMIT;END IF;END WHILE;END; //DELIMITER ;#执⾏存储过程⽣成测试数据CALL pre_test(); 第⼆步:分三中情况进⾏测试,分别是: 第⼀种情况:in和or所在列为主键的情形。

数据库优化方案

数据库优化方案

数据库优化方案1. 高效地进行SQL语句设计:通常情况下,可以采用下面的方法优化SQL对数据操作的表现:(1)减少对数据库的查询次数,即减少对系统资源的请求,使用快照和显形图等分布式数据库对象可以减少对数据库的查询次数。

(2)尽量使用相同的或非常类似的SQL语句进行查询,这样不仅充分利用SQL共享池中的已经分析的语法树,要查询的数据在SGA中命中的可能性也会大大增加。

(3)避免不带任何条件的SQL语句的执行。

没有任何条件的SQL语句在执行时,通常要进行FTS,数据库先定位一个数据块,然后按顺序依次查找其它数据,对于大型表这将是一个漫长的过程.(4)如果对有些表中的数据有约束,最好在建表的SQL语句用描述完整性来实现,而不是用SQL 程序中实现。

一、操作符优化:1、IN操作符用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格.但是用IN的SQL性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。

由此可见用IN的SQL 至少多了一个转换的过程。

一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL 就不能转换了.在业务密集的SQL当中尽量不采用IN操作符.优化sql时,经常碰到使用in的语句,一定要用exists把它给换掉,因为Oracle在处理In 时是按Or的方式做的,即使使用了索引也会很慢。

2、NOT IN操作符强列推荐不使用的,因为它不能应用表的索引。

用NOT EXISTS或(外连接+判断为空)方案代替3、IS NULL或IS NOT NULL操作判断字段是否为空一般是不会应用索引的,因为B树索引是不索引空值的。

用其它相同功能的操作运算代替,a is not null改为a>0 或a>’’等.不允许字段为空,而用一个缺省值代替空值,如业扩申请中状态字段不允许为空,缺省为申请。

sql语句优化之SQLServer(详细整理)

sql语句优化之SQLServer(详细整理)

sql语句优化之SQLServer(详细整理)这篇⽂章主要介绍了sql语句优化之SQL Server篇,整理的⽐较详细,推荐收藏MS SQL Server查询优化⽅法查询速度慢的原因很多,常见如下⼏种1、没有索引或者没有⽤到索引(这是查询慢最常见的问题,是程序设计的缺陷)2、I/O吞吐量⼩,形成了瓶颈效应。

3、没有创建计算列导致查询不优化。

4、内存不⾜5、⽹络速度慢6、查询出的数据量过⼤(可以采⽤多次查询,其他的⽅法降低数据量)7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)8、sp_lock,sp_who,活动的⽤户查看,原因是读写竞争资源。

9、返回了不必要的⾏和列10、查询语句不好,没有优化可以通过如下⽅法来优化查询1、把数据、⽇志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在⽀持。

数据量(尺⼨)越⼤,提⾼I/O越重要.2、纵向、横向分割表,减少表的尺⼨(sp_spaceuse)3、升级硬件4、根据查询条件,建⽴索引,优化索引、优化访问⽅式,限制结果集的数据量。

注意填充因⼦要适当(最好是使⽤默认值0)。

索引应该尽量⼩,使⽤字节数⼩的列建索引好(参照索引的创建),不要对有限的⼏个值的字段建单⼀索引如性别字段5、提⾼⽹速;6、扩⼤服务器的内存,Windows 2000和SQL server 2000能⽀持4-8G的内存。

配置虚拟内存:虚拟内存⼤⼩应基于计算机上并发运⾏的服务进⾏配置。

运⾏ Microsoft SQL Server? 2000 时,可考虑将虚拟内存⼤⼩设置为计算机中安装的物理内存的 1.5 倍。

如果另外安装了全⽂检索功能,并打算运⾏ Microsoft 搜索服务以便执⾏全⽂索引和查询,可考虑:将虚拟内存⼤⼩配置为⾄少是计算机中安装的物理内存的 3 倍。

将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存⼤⼩设置的⼀半)。

数据库查询优化-20条必备sql优化技巧

数据库查询优化-20条必备sql优化技巧

数据库查询优化-20条必备sql优化技巧0、序⾔本⽂我们来谈谈项⽬中常⽤的 20 条 MySQL 优化⽅法,效率⾄少提⾼ 3倍!具体如下:1、使⽤ EXPLAIN 分析 SQL 语句是否合理使⽤ EXPLAIN 判断 SQL 语句是否合理使⽤索引,尽量避免 extra 列出现:Using File Sort、Using Temporary 等。

2、必须被索引重要SQL必须被索引:update、delete 的 where 条件列、order by、group by、distinct 字段、多表 join 字段。

3、联合索引对于联合索引来说,如果存在范围查询,⽐如between、>、<等条件时,会造成后⾯的索引字段失效。

对于联合索引来说,要遵守最左前缀法则:举列来说索引含有字段 id、name、school,可以直接⽤ id 字段,也可以 id、name 这样的顺序,但是 name; school 都⽆法使⽤这个索引。

所以在创建联合索引的时候⼀定要注意索引字段顺序,常⽤的查询字段放在最前⾯。

4、强制索引必要时可以使⽤ force index 来强制查询⾛某个索引: 有的时候MySQL优化器采取它认为合适的索引来检索 SQL 语句,但是可能它所采⽤的索引并不是我们想要的。

这时就可以采⽤ forceindex 来强制优化器使⽤我们制定的索引。

5、⽇期时间类型对于⾮标准的⽇期字段,例如字符串的⽇期字段,进⾏分区裁剪查询时会导致⽆法识辨,依旧⾛全表扫描。

尽管 TIMESTAMEP 存储空间只需要 datetime 的⼀半,然⽽由于类型 TIMESTAMP 存在性能问题,建议你还是尽可能使⽤类型 DATETIME。

(TIMESTAMP ⽇期存储的上限为2038-01-19 03:14:07,业务⽤ TIMESTAMP 存在风险;)6、禁⽌使⽤ SELECT *SELECT 只获取必要的字段,禁⽌使⽤ SELECT *。

SQL优化案例(2):OR条件优化

SQL优化案例(2):OR条件优化

SQL优化案例(2):OR条件优化接下来上⼀篇⽂章《 SQL优化案例(1):隐式转换》的介绍,此处内容围绕OR的优化展开。

在MySQL中,同样的查询条件,如果变换OR在SQL语句中的位置,那么查询的结果也会有差异,在多个复杂的情况下,可能会带来索引选择不佳的性能隐患,为了避免执⾏效率⼤幅度下降的问题,我们可以适当考虑使⽤统⼀所有对查询逻辑复杂的SQL进⾏分离。

常见OR使⽤场景,请阅读以下案例。

案例⼀:不同列使⽤OR条件查询1.待优化场景SELECT....FROM`t1` aWHERE a.token= '16149684'AND a.store_id= '242950'AND(a.registrationId IS NOT NULLAND a.registrationId<> '')OR a.uid= 308475AND a.registrationId IS NOT NULLAND a.registrationId<> ''执⾏计划+--------------+-----------------------+-----------------+----------------+-------------------+-------------------+---------------+----------------+---------------------------------------------+| id | select_type | table | type | key | key_len | ref | rows | Extra |+--------------+-----------------------+-----------------+----------------+-------------------+-------------------+---------------+----------------+---------------------------------------------+| 1 | SIMPLE | a | range |idx_registrationid | 99 | | 100445 | Using index condition; Using where |+--------------+-----------------------+-----------------+----------------+-------------------+-------------------+---------------+----------------+---------------------------------------------+共返回1⾏记录,花费 5 ms 。

sql注入-输入’or1=1#

sql注入-输入’or1=1#

பைடு நூலகம்
在mysql中是注释符这样井号后面的内容将被mysql视为注释内容这样就不会去执行了换句话说以下的两句sql语句等价
sql注入 -输入 ’or1=1#
比如:在用户名输入框中输入:’or 1=1#,密码随便输入,这时候的合成后的SQL查询语句为: select * from users where username='' or 1=1#' and password=md5('') 语义分析:“#”在mysql中是注释符,这样井号后面的内容将被mysql视为注释内容,这样就不会去执行了,换句话说,以下的两句sql语 句等价: select * from users where username='' or 1=1#' and password=md5('') 等价于 select * from users where username='' or 1=1 因为1=1永远都是成立的,即where子句总是为真,将该sql进一步简化之后,等价如下select语句: select * from users 没错,该sql语句的作用是检索users表中的所有字段

MySQL优化——or条件优化

MySQL优化——or条件优化

MySQL优化——or条件优化 MySQL5.0和更新版本中引⼊了⼀种叫:索引合并(Index merge)的策略,⼀定程度上可以使⽤表上多个单列索引来定位指定的⾏。

该特性主要应⽤于以下三种场景: 1. 对or语句求并集,如查询select * from film_actor where c1 = "xxx" or c2 = "xxx"时,如果c1和c2列上分别有索引,可以按照c1和c2条件进⾏查询,再将查询结果合并(union)操作,得到最终结果。

2. 对and语句求交集,如查询select * from film_actor where c1 = "xxx" and c2 = "xxx"时,如果c1和c2列上分别有索引,可以按照c1和c2条件进⾏查询,再将查询结果取交集(intersect)操作,得到最终结果。

3. 组合前两种情况的合并及相交。

该新特性可以在⼀些场景中⼤幅度提升查询性能,但受限于MySQL糟糕的统计信息,也导致很多查询场景查询性能极差甚⾄导致数据库崩溃。

以select * from film_actor where c1 = "xxx" and c2 = "xxx"为例: 1. 当c1列和c2列选择性较⾼时,按照c1和c2条件进⾏查询性能⾼且返回数据集较⼩,再对两个数据量较⼩的数据集求交集的操作成本也⽐较低,最终整个语句查询⾼效; 2. 当c1列或c2列选择性较差且统计信息不准时,⽐如整表数据量1000万,按照c2列条件返回800万数据,按照c1列返回100条数据,此时按照c2列条件进⾏索引扫描+聚集索引查询的操作成本极⾼(可能是整表扫描的百倍消耗),对100 条数据和800万数据求交集的成本也极⾼,最终导致整条SQL需要消耗⼤量CPU和IO资源,且相应时间超长,⽽如果值使⽤c1列的索引,查询消耗资源少且性能较⾼。

SQLServer复合查询条件(AND,OR,NOT)对NULL值的处理方法

SQLServer复合查询条件(AND,OR,NOT)对NULL值的处理方法

SQLServer复合查询条件(AND,OR,NOT)对NULL值的处理⽅法在SQL的3值逻辑下,⼀个查询条件可以产⽣以下三种情况:TRUE,FALSE,NULL。

只有那些满⾜WHERE⼦句的值是TRUE的记录才出现在结果表中。

NULL值影响查询条件的结果,并且结果很微妙。

以下是SQL中AND,OR,NOT的真值表。

表1 AND的真值表TRUE FALSE NULLTRUE TRUE FALSE NULLFALSE FALSE FALSE FALSENULL NULL FALSE NULL表2 OR的真值表TRUE FALSE NULLTRUE TRUE TRUE TRUEFALSE TRUE FALSE NULLNULL TRUE NULL NULL表3 NOT的真值表TRUE FALSE NULLFALSE TRUE NULL当两个以上的查询条件与AND、OR、NOT组合时,NOT的优先级最⾼,其次是AND,最后是OR。

为了避免歧义和确保可移植性最好使⽤括号。

A BETWEENB ANDC 等价于 (A>=B) AND (A<=C),因此根据真值表可以得出BETWEEN ⼦句中处理NULL值的规则。

同样,A IN(B,C,D) 等价于(A=B)OR(A=C)OR(A=D), 根据真值表,只要这三个表达式中有⼀个为NULL,结果返回肯定是NULL。

因此,BETWEEN⼦句和IN⼦句并不增加SQL语句的表达能⼒。

SQL 中有NULL 值测试,即:字段 IS (NOT) NULL ,但它的返回结果只有两种情况:TRUE或者FALSE。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

如何优化带or条件的sql----------本文章转自网络,互相学习,互相帮助以下为转帖内容:======================================================================================== ========今天在论坛上看到了一个帖子,问题如下:select * from ccwhere ((a1 ='ffff' and z1='mmmm') or (b1='sss' and z2='nnnn'))and c1 ='ggggg'其中表有30万行数据,返回的数据10行左右,怎样创建index访问最快。

按照别人的说法测试了一下,步骤如下:create table CC(A1 VARCHAR2(5),Z1 VARCHAR2(5),B1 VARCHAR2(5),Z2 VARCHAR2(5),C1 VARCHAR2(5))insert into cc values('dffd','dfsd','fdf','fdsfs','sfds');--重复插入2097152条,对查询时间可能有影响SQL> select count(*) from cc;COUNT(*)----------2097160SQL> set timing onSQL> edit已写入file afiedt.buf1 select * from cc2 where ((a1='ffff'and z1='mmmm') or (b1='sss' and z2='nnnn'))3* and c1='ggggg'--无索引情况下or查询SQL> /A1 Z1 B1 Z2 C1----- ----- ----- ----- -----ffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn ggggg已选择8行。

已用时间: 00: 00: 00.21SQL> edit已写入file afiedt.buf1 select * from cc2 where (a1='ffff'and z1='mmmm')3 and c1='ggggg'4 union5 select * from cc6 where (b1='sss' and z2='nnnn')7* and c1='ggggg'--无索引情况下union查询,注意与union all查询结果的区别SQL> /A1 Z1 B1 Z2 C1----- ----- ----- ----- -----ffff mmmmm sss nnnn ggggg已用时间: 00: 00: 00.33SQL> edit已写入file afiedt.buf1 select * from cc2 where (a1='ffff'and z1='mmmm')3 and c1='ggggg'4 union all5 select * from cc6 where (b1='sss' and z2='nnnn')7* and c1='ggggg'--无索引情况下union all查询SQL> /A1 Z1 B1 Z2 C1----- ----- ----- ----- -----ffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn ggggg已选择8行。

已用时间: 00: 00: 00.35SQL> create index cc_idx on cc(c1);索引已创建。

已用时间: 00: 00: 11.14SQL> edit已写入file afiedt.buf1 select * from cc2 where ((a1='ffff'and z1='mmmm') or (b1='sss' and z2='nnnn'))3* and c1='ggggg'--有索引or查询,注意,虽然没有列出执行计划,索引肯定用到了。

SQL> /A1 Z1 B1 Z2 C1----- ----- ----- ----- -----ffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn ggggg已选择8行。

已用时间: 00: 00: 00.01SQL> edit已写入file afiedt.buf1 select * from cc2 where (a1='ffff'and z1='mmmm')3 and c1='ggggg'4 union5 select * from cc6 where (b1='sss' and z2='nnnn')7* and c1='ggggg'--有索引union查询,注意与union all查询结果的区别SQL> /A1 Z1 B1 Z2 C1----- ----- ----- ----- -----ffff mmmmm sss nnnn ggggg已用时间: 00: 00: 00.00SQL> edit已写入file afiedt.buf1 select * from cc2 where (a1='ffff'and z1='mmmm')3 and c1='ggggg'4 union all5 select * from cc6 where (b1='sss' and z2='nnnn')7* and c1='ggggg'--有索引union all查询SQL> /A1 Z1 B1 Z2 C1----- ----- ----- ----- -----ffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn ggggg已选择8行。

已用时间: 00: 00: 00.01SQL>create index CC_IDX2 on CC (A1, Z1);SQL>create index CC_IDX3 on CC (B1, Z2);SQL>set autot onSQL> edit已写入file afiedt.buf1 select * from cc2 where ((a1='ffff'and z1='mmmm') or (b1='sss' and z2='nnnn'))3* and c1='ggggg'--3索引情况下or查询SQL> /A1 Z1 B1 Z2 C1----- ----- ----- ----- -----ffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn ggggg已选择8行。

已用时间: 00: 00: 00.60--时间明显比单索引扫描时间长执行计划----------------------------------------------------------Plan hash value: 1540710700---------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |---------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 2 | 40 | 4 (0)| 00:00:01 || 1 | CONCATENATION | | | | | ||* 2 | TABLE ACCESS FULL| CC | 1 | 20 | 2 (0)| 00:00:01 |--注意:从执行计划上可以看到,|* 3 | TABLE ACCESS FULL| CC | 1 | 20 | 2 (0)| 00:00:01 |--索引失效,全表扫描---------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------2 - filter("B1"='sss' AND "Z2"='nnnn' AND "C1"='ggggg')3 - filter("C1"='ggggg' AND "A1"='ffff' AND "Z1"='mmmm' AND(LNNVL("B1"='sss') OR LNNVL("Z2"='nnnn')))Note------ dynamic sampling used for this statement统计信息----------------------------------------------------------0 recursive calls0 db block gets17673 consistent gets405 physical reads0 redo size703 bytes sent via SQL*Net to client400 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)8 rows processedSQL> edit已写入file afiedt.buf1 select * from cc2 where (a1='ffff'and z1='mmmm')3 and c1='ggggg'4 union5 select * from cc6 where (b1='sss' and z2='nnnn')7* and c1='ggggg'--3索引情况下union查询,注意与union all查询结果的区别SQL> /A1 Z1 B1 Z2 C1----- ----- ----- ----- -----ffff mmmmm sss nnnn ggggg已用时间: 00: 00: 00.10--时间明显比单索引扫描时间长执行计划----------------------------------------------------------Plan hash value: 1185376162-----------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 4 | 80 | 10 (60)| 00:00:01 || 1 | SORT UNIQUE | | 4 | 80 | 10 (60)| 00:00:01 || 2 | UNION-ALL | | | | |||* 3 | TABLE ACCESS BY INDEX ROWID| CC | 2 | 40 | 4 (0)| 0 0:00:01 ||* 4 | INDEX RANGE SCAN | CC_IDX2 | 34 | | 3 (0)| 00:00:01 ||* 5 | TABLE ACCESS BY INDEX ROWID| CC | 2 | 40 | 4 (0)| 0 0:00:01 ||* 6 | INDEX RANGE SCAN | CC_IDX3 | 34 | | 3 (0)| 00:00:01 |-----------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------3 - filter("C1"='ggggg')4 - access("A1"='ffff' AND "Z1"='mmmm')5 - filter("C1"='ggggg')6 - access("B1"='sss' AND "Z2"='nnnn')Note------ dynamic sampling used for this statement统计信息----------------------------------------------------------9 recursive calls0 db block gets174 consistent gets7 physical reads0 redo size637 bytes sent via SQL*Net to client400 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client1 sorts (memory)--注意,进行了排序0 sorts (disk)1 rows processedSQL> edit已写入file afiedt.buf1 select * from cc2 where (a1='ffff'and z1='mmmm')3 and c1='ggggg'4 union all5 select * from cc6 where (b1='sss' and z2='nnnn')7* and c1='ggggg'--3索引情况下union all查询SQL> /A1 Z1 B1 Z2 C1----- ----- ----- ----- -----ffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn gggggffff mmmmm sss nnnn ggggg已选择8行。

相关文档
最新文档