SQL 數據優化索引建suo避免全表掃描

来源:http://www.cnblogs.com/zaisheng/archive/2017/01/03/6243640.html
-Advertisement-
Play Games

首先什麼是全表掃描和索引掃描?全表掃描所有數據過一遍才能顯示數據結果,索引掃描就是索引,只需要掃描一部分數據就可以得到結果。如果數據沒建立索引。 無索引的情況下搜索數據的速度和占用記憶體就會比用索引的檢索慢和高。下麵是一個例子 1:無索引的情況 Product表,裡面沒有任何索引,如下圖: 從上圖中, ...


  首先什麼是全表掃描和索引掃描?全表掃描所有數據過一遍才能顯示數據結果,索引掃描就是索引,只需要掃描一部分數據就可以得到結果。如果數據沒建立索引。 無索引的情況下搜索數據的速度和占用記憶體就會比用索引的檢索慢和高。下麵是一個例子

1:無索引的情況

  Product表,裡面沒有任何索引,如下圖:

 

從上圖中,我悲劇的看到了,物理讀是9次,也就說明走了9次硬碟,你也可以想到,走硬碟的目的是為了拿數據,邏輯讀有1636次,要註意的是這裡

的”次“是“頁”的意思,也就是在記憶體中走了1636個數據頁,我用dbcc ind 給你看一下,是不是有1636個表數據頁。

這裡有1637個數據頁的原因是第一個是IAM跟蹤頁。

 

2:有聚集索引的情況

     下麵我在Product表中建一個product_idx_productid的聚集索引,然後再次看看io情況,如下圖:

當你看到這個”邏輯讀“為3次的時候,你是不是已經瘋了。。。在多達1636個數據頁中找到目標數據,只需3次。。。

以上參考   http://www.cnblogs.com/huangxincheng/category/555253.html

 

那麼如何避免全表掃描 來提高SQL檢索的性能?下麵就有幾種方法總結

以下參考 http://lzz7658823.iteye.com/ 1.對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。

2.應儘量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null
可以在num上設置預設值0,確保表中num列沒有null值,然後這樣查詢:
select id from t where num=0

3.應儘量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。

4.應儘量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num=10 or num=20
可以這樣查詢:
select id from t where num=10
union all
select id from t where num=20

5.in 和 not in 也要慎用,否則會導致全表掃描,如:
select id from t where num in(1,2,3)
對於連續的數值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3

6.下麵的查詢也將導致全表掃描:
select id from t where name like '%abc%'
若要提高效率,可以考慮全文檢索。

7.如果在 where 子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變數,但優化程式不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變數的值還是未知的,因而無法作為索引選擇的輸入項。如下麵語句將進行全表掃描:
select id from t where num=@num
可以改為強制查詢使用索引:
select id from t with(index(索引名)) where num=@num

8.應儘量避免在 where 子句中對欄位進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where num/2=100
應改為:
select id from t where num=100*2

9.應儘量避免在where子句中對欄位進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where substring(name,1,3)='abc'--name以abc開頭的id
select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
應改為:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'

10.不要在 where 子句中的“=”左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。

11.在使用索引欄位作為條件時,如果該索引是複合索引,那麼必須使用到該索引中的第一個欄位作為條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應儘可能的讓欄位順序與索引順序相一致。

12.不要寫一些沒有意義的查詢,如需要生成一個空表結構:
select col1,col2 into #t from t where 1=0
這類代碼不會返回任何結果集,但是會消耗系統資源的,應改成這樣:
create table #t(...)

13.很多時候用 exists 代替 in 是一個好的選擇:
select num from a where num in(select num from b)
用下麵的語句替換:
select num from a where exists(select 1 from b where num=a.num)

14.並不是所有索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重覆時,SQL查詢可能不會去利用索引,如一表中有欄位sex,male、female幾乎各一半,那麼即使在sex上建了索引也對查詢效率起不了作用。

15.索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。

14.並不是所有索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重覆時,SQL查詢可能不會去利用索引,如一表中有欄位sex,male、female幾乎各一半,那麼即使在sex上建了索引也對查詢效率起不了作用。
18.儘可能的使用 varchar/nvarchar 代替 char/nchar ,因為首先變長欄位存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的欄位內搜索效率顯然要高些。

20.儘量使用表變數來代替臨時表。如果表變數包含大量數據,請註意索引非常有限(只有主鍵索引)。

21.避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。

23.在新建臨時表時,如果一次性插入數據量很大,那麼可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數據量不大,為了緩和系統表的資源,應先create table,然後insert。

25.儘量避免使用游標,因為游標的效率較差,如果游標操作的數據超過1萬行,那麼就應該考慮改寫。


28.在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF 。無需在執行存儲過程和觸發器的每個語句後向客戶端發送 DONE_IN_PROC 消息。

30.儘量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理         

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、前端MVC概要 1.1、庫與框架的區別 框架是一個軟體的半成品,在全局範圍內給了大的約束。庫是工具,在單點上給我們提供功能。框架是依賴庫的。AngularJS是框架而jQuery則是庫。 1.2、AMD與CMD 在傳統的非模塊化JavaScript開發中有許多問題:命名衝突、文件依賴、跨環境共用 ...
  • 查看npm的所有版本 運行命令: 命令運行後,會輸出到目前為止npm的所有版本。 將npm升級到某個版本。 升級前本機版本號是2.14.12,可通過npm -v查看。 命令運行,升級到3.1.0版: 升級完成後,查看一下本機npm的版本,就是升級後的版本。 參考: Updating npm ...
  • 01.01_電腦基礎知識(電腦概述)(瞭解) A:什麼是電腦?電腦在生活中的應用舉例 電腦(Computer)全稱:電子電腦,俗稱電腦。是一種能夠按照程式運行,自動、高速處理海量數據的現代化智能電子設備。由硬體和軟體所組成,沒有安裝任何軟體的電腦稱為裸機。常見的形式有台式電腦、筆記本 ...
  • 一、下載並安裝class-dump 下載class-dump-3.5.dmg 點擊下載 下載完成以後雙擊.dmg的文件,將裡面的class-dump拷貝到/usr/local/bin 設置許可權chmod 777 /usr/local/bin/class-dump 在控制台輸入class-dump,顯 ...
  • JDK安裝與配置 一、下載 JDK是ORACLE提供免費下載使用的,官網地址:https://www.oracle.com/index.html 一般選擇Java SE版本即可,企業版的選擇Java EE 下載的JDK版本(目前最新的是JDK8u112) JDK的開發包以及相關的文檔下載 勾選同意, ...
  • 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6241354.html 首先看一張國內Top500 Android應用中它們用到的第三方推送以及所占數量: 現在總結下Android平臺下幾種推送方案的基本情況以及優缺點: 一、使用GCM(Google Clo ...
  • SqlServer的性能問題大部分是因為缺少索引或索引不當導致的,因此熟悉掌握索引相關知識是精通SqlServer的第一步。我們可以從索引的數據結構瞭解索引的本質;掌握聚集索引和非聚集索引的區別有助於我們在不同場景下走出誤區、建立合適索引;在一些場景下你也有可能需要用到索引視圖 索引的數據結構 在S ...
  • 記得在做項目的時候, 聽到過一句話, 儘量不要使用子查詢, 那麼這一篇就來看一下, 這句話是否是正確的. 那在這之前, 需要介紹一些概念性東西和mysql對語句的大致處理. 當Mysql Server的連接線程接收到Client發送過來的SQL請求後, 會經過一系列的分解Parse, 進行相應的分析 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...