语句调优之找茬
本文讲一个某司招聘用到的面试题,请列举如下语句有哪些会造成效能不佳的地方并说明原因与建议写法:
1. SELECT * FROM Employee AS emp
2. LEFT JOIN Business AS bus ON emp.id = bus.id
3. RIGHT JOIN Person AS per ON per.id is not null
4. LEFT JOIN ( SELECT * FROM Product
5. WHERE product_id <> '' ) AS pro ON per.product_id = pro.product_id
6. RIGHT JOIN Order AS ord ON emp.id = ord.id or per.order_id = ord.id or pro.order_id = ord.id
7. LEFT JOIN Customer AS cus ON ord.customer_id = cus.id
8. LEFT JOIN Sales AS sal ON cus.sales_id = sal.id
9. LEFT JOIN Contracts AS con ON cus.contract_id = con.id
10. LEFT JOIN Document AS doc ON con.document_id = doc.id
11. WHERE 1=1 and emp.country in ('tpe','jpn') and emp.phone like '%000%'
12. and convert(varchar,joindate,111) > convert(varchar,getdate()-100,111)
13. or name not in (SELECT TOP 100 name from blocklist)
14. or (CASE sex WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE 3) < 3
我能想到的有如下几点,可能不准确,仅供参考吧:
- 第1行:不建议
SELECT *
,需要返回的字段建议逐一注明 - 第3行:
per.id is not null
在外联条件里做过滤会导致返回的结果集不准确 - 第6行:ON连接条件用了2个or,建议改为3个
right join
- 第11行:不建议使用
1=1
,无意义 - 第11行:
like '%000%'
不高效 - 第12行:字段joindate没有alias
- 第12行:对字段做convert计算会导致索引失效
- 第12行:varchar没有指定大小
- 第12行:建议改为
dateadd(day,datediff(day,'19000101',getdate()),'19000101')
- 第13行:字段name没有alias
- 第13行:建议
not in
改为not exists
- 第13行:使用
select top
未指定order by
则返回结果有可能不准确 - 第14行:字段sex没有alias
- 第14行:case没有end结束符