mysql查詢語句的效率
幾篇文章的摘錄。
為什么MySQL不推薦使用子查詢和join(開發程序)
1子查詢,效率差。原因:執行子查詢時,會創建臨時表,查詢完畢后再刪除它,所以子查詢的速度會收到影響。
2JOIN。小表驅動大表,通過索引字段進行關聯,只適用較少的數據量。
3從開發程序看,數據庫只作為儲存數據的工具來用,業務邏輯放到應用控制層上去實現。
推薦,大數據下,為了保證效率,推薦根據索引單表取得數據,然后在程序里面做join, merge數據。??只開發時,在控制層實現業務邏輯??。
MySQL大表優化方案
單表優化:
一般以整型值為主的表在千萬級
以下,字符串為主的表在五百萬
以下的表進行單表優化。
除非單表數據未來會一直不斷上漲,否則不要一開始就考慮拆分,拆分會帶來邏輯、部署、運維的各種復雜度。
字段:
- 適用tinyint, smallint, medium_int代替int, 非負加上unsigned
- varchar的長度要根據實際需求設定
- 用enum或int,代替varchar
- 盡量使用
TIMESTAMP
而非DATETIME 為什么?(一篇博客)
- datetime類型適合記錄數據的原始的創建時間。
- 可以為空值。實際儲存格式由創表者設定。
- 和時區無關。
- 用now()來插入系統的當前時間。
- timestamp類型適合記錄數據的最后修改時間,因為可以設定當其他字段的值變更后,timestamp自動更新。
- 可以為空值,但不能自定義值。
- 有時區,可以時區轉化。
- 值的范圍是:1970或晚於2037。
- 值以UTC格式保存。
- 默認值: current_timestamp()
- 默認情況下以后任何時間修改表中的記錄時,對應記錄的timestamp值會自動被更新為當前的系統時間。
- datetime類型適合記錄數據的原始的創建時間。
- 單表設計,字段數量要控制,最好20個以內。
- 避免用null字段, 很難查詢優化且占用額外索引空間
索引:
- 索引根據實際需要來設置,不是越多越好,索引本身是占用內存空間的。
- 在where和order by上會用到的columns, 是否建立索引,可以使用explain查看是用了索引還是全表掃描
- 應盡量避免在where上對字段進行null值的判斷,否則導致引擎放棄使用索引,而改用全表掃描。
- 如性別列這種只有男,女,中性三種值的字段/列,無需建立索引。
- 盡量不用foreign key,用應用程序來保證約束。
- 盡量不用unique, 用應用程序來保證約束。
- 使用多列索引時主意順序和查詢條件保持一致,同時刪除不必要的單列索引
- 字符字段只建前綴索引, 字符字段最好不要做主鍵.
查詢:
- 不做列運算:
SELECT id WHERE age + 1 = 10
,任何對列的操作都將導致全表掃描,它包括數據庫教程函數、計算表達式等等,查詢時要盡可能將操作移至等號右邊。 - sql語句盡量簡單,大語句拆成小語句,減少鎖時間;一條大語句可以堵死整個庫。
- 不用select *
- OR改成IN。用OR的時間復雜度是N,用in的時間復雜度是logN。in的個數在200以內。
- 不用函數和觸發器,在應用程序中實現!!
- 避免模糊查詢 like "%xxxx"。會導致索引字典失效。
- 少用JOIN,更要減少使用子查詢。
- 使用同類型比較: “123”和“123”比較, 123和123比較。
- 盡量避免在where子句中使用 !=和<>操作符,因為會導致全表掃描,而不是使用索引。
- 對於連續數值,使用between, 不要用in。SELECT id FROM t WHERE num BETWEEN 1 AND 5
- 列表數據不要取全表數據,用limit分頁查詢,每頁也不要太大。
其他優化方案:
- 引擎的選擇
- 系統調優參數
- 升級硬件
- 緩存
- 表分區
- 對表進行垂直拆分
- 水平拆分(非常復雜)