在編寫查詢sql的時候,有一些技巧可以提公升查詢效能,總結如下:
not exists 代替 not in
盡量避免not in (子查詢)的查詢,如果是not in (列表)倒是可以接受的,因為not in (子查詢)可以使用not exists代替,使用not exists那麼就將子查詢變成和關聯查詢,至少可以使用主鍵的索引了。
迎合和討好mysql的優化器,讓查詢sql走索引;
舉個例子,比如,你的一張表的主鍵id是從1開始的,那麼
select * from t_x order by id
如果對上面的sql調整為如下:
select * from tx where id > 0 order by id
那麼這樣是不好的,原因就是使用了索引排序,這就是使用了順序掃瞄索引,由於該索引未能覆蓋查詢的所有列,因此從一條索引記錄移動到下一條記錄時,不得不每掃瞄一條一條索引記錄就都回表查詢一次對應的行。這基本上都是隨機i/o,因此,這種情況下按照索引順序讀取資料的速度通常表順序地全表掃瞄慢。
如果需求的sql如下:
select id from t_x order by id
如果對上面的sql調整如下:
select id from t_x where id > 0 order by id
那麼explain的查詢計畫的type就是rang了,這裡有個點需要注意,rows的函式比 select id from t_x order by id這個要多,但是 select id from t_x order by id這個的explain 的type 是index;
總結:如果要使用索引掃瞄來排序,要避免排序的索引不能覆蓋查詢的列的情況。因此,設計索引時,如果可能,設計索引時要能滿足乙個索引既可以滿足排序,又可用於查詢行(即覆蓋查詢的列)。
另外注意:就算你想使用索引排序的功能,也不是任何情況都可以可以使用索引排序,這裡有一些需要注意的地方,比如多表關聯時,order by的字段全部為第乙個表時,才能使用索引排序。order by 子句和查詢型查詢的限制是一樣的:需要滿足索引的最左字首的要求,否則,mysql都需要執行排序操作,而無法利用索引排序。
有一種情況order by 子句可以不滿足索引的最左字首的要求,就是前導列為常量的時候。注意:這個前導列一定是最左字首。其實,這樣算作曲線滿足order by 子句的索引的最左字首的要求了吧。
延遲關聯查詢
如果關聯查詢的結果是所有列,或者查詢的索引不能覆蓋查詢的列,那麼就要把查詢所有列的查詢進行延遲關聯,先通過索引查詢出索引列(索引覆蓋),然後和查詢所有列的查詢進行關聯,這就是延遲關聯。
4.避免多個範圍查詢
如果多個範圍查詢,那麼第乙個範圍查詢可以使用索引,後面的範圍查詢就不能使用了索引。但是對於多個等值條件查詢(即使用in(x,y,z))則沒有這個限制。雖然範圍查詢和in的執行計畫的type列都是range,從explain的輸出很難區分mysql是要查詢範圍值,還是查詢列表值。
SQL 注意事項
選擇表名 配置ctrl 3 能夠select 桌 use nb go 物 storedprocedure dbo sp select 指令碼日期 05 28 2015 21 46 25 set ansi nulls on go set quoted identifier on go create p...
sql 注意事項
在 oracle 都是不等於號的意思。都可以使用。但是奇怪的是,我想拿出price 不是180000旳商品時 select id,name,from product where price 180000 執行這個語句是,price null 的記錄不出來,也就是拿不到price 是null的商品,必...
mysql多表查詢注意事項 MySQL的多表查詢
一 表的加法 例如 將course和course1兩張表合併 兩張表的資料分別如圖所示 course表的資料course1表的資料 用union合併兩張表 course course1 去重 用union all合併兩張表course course1 不去重 注意 字段順序應保持一致。二,多表聯結 ...