SQL查询,过滤条件使用and和,有什么区别?

对一个内存表进行SQL查询,过滤条件使用and和,有什么区别?如果过滤条件有多个,条件的先后顺序不同,会影响性能吗?为什么?

请先 登录 后评论

1 个回答

jiajia xu

,进行连接时,在查询时会按照顺序对,前的条件层层进行过滤,因此,条件的先后顺序不同,在执行查询时会有区别。当过滤条件都与序列无关时,条件的先后顺序不影响查询结果,建议将过滤能力强的条件放前面,这样可以极大的减少后面查询的数据量;当过滤条件包含序列相关(如:deltas, ratios, ffill, move, prevcumsum)的条件时,先后顺序会影响查询结果。

 

and进行连接时,当过滤条件都与序列无关时,系统内部对and进行了优化,即将and转换为,,此时,使用and和使用,连接的sql语句性能差别不大。包含顺序相关的条件时,会对所有条件在原表内分别进行筛选后再将结果取交集。条件之间的顺序,不影响查询性能,也不影响最终的执行结果。

 

总体来说,连接条件不包含序列相关函数时,使用,and都可以。但包含序列相关条件时,必须使用and

 

举例说明,创建内存表:

n=1000000
date=take(2019.01.01..2019.01.03,n)
sym = take(`C`MS`MS`MS`IBM`IBM`IBM`C`C$SYMBOL,n)
price= take(49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29,n)
qty = take(2200 1900 2100 3200 6800 5400 1300 2500 8800,n)
t=table(date, sym, price, qty)

全部为序列无关的条件时,,和and连接相同过滤条件,query语句执行性能差别不大,结果一致:

timer(1000) t1=select * from t where qty>2000 and date=2019.01.02 and sym=`C  //3s 370ms
timer(1000) t2=select * from t where qty>2000, date=2019.01.02, sym=`C    //3s 712ms
timer(1000) t11=select * from t where date=2019.01.02 and sym=`C and qty>2000  //2s 562ms
timer(1000) t22=select * from t where date=2019.01.02, sym=`C, qty>2000    //2s 562ms
 
each(eqObj, t1.values(), t2.values())   // true true true true
each(eqObj, t11.values(), t22.values())  // true true true true
each(eqObj, t2.values(), t22.values())   // true true true true


包含序列相关的条件时,and连接的条件改变顺序,不影响查询性能和最终结果,因为这些条件是并列关系,每个条件都是对原表进行筛选,再将筛选后的结果取交集。但使用,连接条件时,条件筛选是递进的,即先使用第一个,前的条件对原表进行过滤,得到一个新表,再使用第二个,前的条件对这个新表进行过滤,依此进行下去,当序列相关的条件在后面出现时,已经无法对数据按照原表的顺序进行操作了:

timer(1000) t3=select * from t where ratios(qty)>1, date=2019.01.02, sym=`C    //5s 750ms
timer(1000) t4=select * from t where ratios(qty)>1 and date=2019.01.02 and sym=`C  //5s 417ms
 
timer(1000) t33=select * from t where date=2019.01.02, sym="C", ratios(qty)>1   //1s 739ms
timer(1000) t44=select * from t where date=2019.01.02 and sym="C" and ratios(qty)>1  //5s 401ms
 
each(eqObj, t3.values(), t4.values())   // 这里看出因为序列条件是第一个,,连接时,首先对数据按照原表的顺序进行操作,后面的条件是与顺序无关的,所以,结果和and连接的保持一致。
each(eqObj, t3.values(), t33.values())  // 这里看出,连接时,条件改变顺序后,两个结果表数据内容不一致。
each(eqObj, t4.values(), t44.values())  // 这里看出and连接时,条件改变顺序后,两个结果表数据保持一致



请先 登录 后评论