因为支付模块重构,造成了一些偶发的BUG,从而是我们的支付记录、微信记录及第三方记录对不上,从而不得不我们一个月的对账工作,经历了不少996,但同时也掌握了一些常用sql查询及优化等...
SELECT * FROM table WHERE type = 1;
以上是一条最简单的sql条件查询语句,那我们如果有2个type需要同时查询呢?
我们可以这样写:
SELECT * FROM table WHERE type = 1 OR type = 2;
如果,我们查出的结果是多个,且需要排序呢?
-- DESC 降序,ASC 升序,默认升序
SELECT * FROM table WHERE type = 1 OR type = 2 ORDER BY aid DESC;
那么,如果是3个type,4个type...甚至n个type呢,岂不是sql会非常长?
我们可以稍微改下:
SELECT * FROM table WHERE type IN (1,2,3...);
-- 注意后面的省略号只是写在伪代码中表示可以有多个
其实相比于or操作,IN不仅仅是让sql语句更简洁,在大数据库查询时性能上更有优势,or的效率为O(n),而in的效率为O(log2n),所有当基数越大,IN的执行效率相对于or来说越有优势。
正常有索引的时候可能感觉并不明显,但是当aid无索引时,执行效率立马就体现出来了...
不信的朋友可以试试100万以上的数据表,过滤无索引字段查询100条以上记录,or的执行时间至少是in的几十倍以上...
然后, 我们再来看看新的需求,有两张表tableA, tableB, tableA中有字段Bid,用于关联tableB表,我们需要过滤tableB的name字段包含“n”字母,进而查询出tableA表的数据...
于是sql变成这样:
SELECT a.* FROM tableA a
WHERE a.Bid
IN (
SELECT b.id FROM tableB b where b.name like "%n%"
);
然而,从执行效率来说,EXISTS是由于IN的,所以上面的sql,我们可以这样写:
SELECT a.* FROM tableA a
WHERE
EXISTS (
SELECT b.id FROM tableB b where b.name like "%n%" AND a.Bid = B.id
);
另外,如果我们使用IN时,如果有2层以上的情况,如:
SELECT a.* FROM tableA a
WHERE a.Bid
IN (
SELECT b.id FROM tableB b
WHERE b.Cid
IN (
SELECT c.id FROM tableC c where c.name like "%n%"
)
);
可以尝试下,哪怕每个表的id和关联id都有索引,但是,仍然是100万+数据表,这个查询会非常慢,此时,我们可以使用JOIN(其实两层的时候也建议用join,虽然写起来麻烦一些,但是效率更高啊)...
SELECT a.* FROM tableA a
JOIN tableB b ON a.Bid = b.id
JOIN tableC c ON b.Cid = c.id
WHERE c.name like "%n%";
这样就将三张表关联起来了,如果有需要,还可以4张,5张表关联...
JOIN还有INNER JOIN, LEFT JOIN, RIGHT JOIN,FULL JOIN四种用法,上面的写法JOIN其实默认就是INNER JOIN...
你一定注意到了,通过join,我们不仅可以用于替换in操作,还可以用于查询多个表的字段,如:
SELECT a.name, b.name, c.name FROM tableA a
JOIN tableB b ON a.Bid = b.id
JOIN tableC c ON b.Cid = c.id
WHERE c.name like "%n%";
当然,对账期间还用到了SET @、GROUP BY、LIKE、NOT LIKE以及COUNT、SUM、CONTAINS等,由于时间关系,就暂不记录了。