查詢慢是和表結構,語句,系統等相關的 建索引等方法都可以改善表結構, 另外如果返回數據量很大,當然會慢,所以你盡量查詢相對有用的數據 再就是查詢語句了 比如用in查詢沒有jion查詢快,還有 between 改成 > <會快 再還有,用子查詢也會慢很多, 如果是一些很復雜的查詢,可以改用存儲過程會好點,有時用臨時表會慢但,從海量數據中查詢取數進行子查詢又不如用臨時錶快,不同的問題用不同的解決方法,看你要哪種了,單看你的問題無法直接判斷。 不過,優化查詢句是關鍵的了。
❷ 從外到內提高SQL Server資料庫性能
如何提高SQL Server資料庫的性能 該從哪裡入手呢?筆者認為 該遵循從外到內的順序 來改善資料庫的運行性能 如下圖
第一層 網路環境
到企業碰到資料庫反映速度比較慢時 首先想到的是是否是網路環境所造成的 而不是一開始就想著如何去提高資料庫的性能 這是很多資料庫管理員的一個誤區 因為當網路環境比較惡劣時 你就算再怎麼去改善資料庫性能 也是枉然
如以前有個客戶 向筆者反映資料庫響應時間比較長 讓筆者給他們一個提高資料庫性能的解決方案 那時 筆者感到很奇怪 因為據筆者所知 這家客戶資料庫的記錄量並不是很大 而且 他們配置的資料庫伺服器硬體很不錯 筆者為此還特意跑到他們企業去查看問題的原因 一看原來是網路環境所造成的 這家企業的客戶機有 多台 而且都是利用集線器進行連接 這就導致企業內部網路廣播泛濫 網路擁塞 而且由於沒有部署企業級的殺毒軟體 網路內部客戶機存在病毒 掠奪了一定的帶寬 不僅資料庫系統響應速度比較慢 而且其他應用軟體 如郵箱系統 速度也不理想
在這種情況下 即使再花十倍 百倍力氣去提升SQL Server資料庫的性能 也是竹籃子打水一場空 因為現在數據冊豎庫伺服器的性能瓶頸根本不在於資料庫本身 而在於企業的網路環境 若網路環境沒有得到有效改善 則SQL Server資料庫性能是提高不上去的
為此 筆者建議這家企業 想跟他們的網路管理員談談 看看如何改善企業的網路環境 減少廣播包和網路沖突;並且有效清除區域網內的病毒 木馬等等 三個月後 我再去回訪這家客戶的時候 他們反映資料庫性能有了很大的提高 而且其他應用軟體 性能也有所改善
所以 當企業遇到資料庫性能突然降低的時候 第一個反應就是查看網路環境 看看其實否有惡化 只有如此 才可以少走冤枉路
第二層 伺服器配置
這里指的伺服器配置 主要是講資料庫伺服器的硬體配置以及周邊配套 雖然說 提高資料庫的硬體配置 需要企業付出一定的代價 但是 這往往是一個比較簡便的方法 比起優化SQL語句來說 其要簡單的多
如企業可以通過增加硬碟的數量來改善資料庫的性能 在實際工作中 硬碟輸入輸出瓶頸經常被資料庫管理員所忽視 其實 到並發訪問比較多的時候 硬碟輸入輸出往往是資料庫性能的一個主要瓶頸之一 此時 若資料庫管理員可以增加幾個硬碟 通過磁碟陣列來分散磁碟的壓力 無疑是提高資料庫性能的一個捷徑
如增加伺服器的內存或者CPU 當資料庫管理員發現資料庫性能的不理想是由內存或者CPU所造成的 此時 任何的改善資料庫伺服器本身的措施都將一物用處 所以 有些資料庫管理專家 把改善伺服器配置當作敗姿亂資料庫性能調整的一個先決條件
如解決部署在同一個資料庫伺服器上的資源爭用問題 雖然我們多次強調 要為資料庫專門部署一個伺服器 但是 不少企業為了降低信息化的成本 往往把資料庫伺服器跟應用伺服器放在同一個伺服器中 這就會導致不同伺服器之間的資源爭用問題 如把文件伺服器跟數據伺服器部署在同一個伺服器中 當對文件伺服器進行備份時 資料庫性能就會有明顯的下降 所以 在資料庫性能發現周期性的變化時 就要考慮是否因為伺服器上不同應用對資源的爭奪所造成的
故 筆者建察檔議 改善資料庫性能時第二個需要考慮的層面 就是要看看能否通過改善伺服器的配置來實現
第三層 資料庫伺服器
當通過改善網路環境或者提高伺服器配置 都無法達到改善資料庫性能的目的時 接下去就需要考察資料庫伺服器本身了 首先 就需要考慮資料庫伺服器的配置
一方面 要考慮資料庫伺服器的連接模式 SQL Server資料庫提供了很多的資料庫模式 不同的資料庫連接模式對應不同的應用 若資料庫管理員能夠熟悉企業自身的應用 並且選擇合適的連接模式 這往往能夠達到改善資料庫性能的目的
其次 合理配置資料庫伺服器的相關作業 如出於安全的需要 資料庫管理員往往需要對資料庫進行備份 那麼 備份的作業放在什麼時候合適呢?當然 放在夜晚 夜深人靜的時候 對資料庫進行備份最好 另外 對於大型資料庫 每天都進行完全備份將會是一件相當累人的事情 雖然累得不是我們 可是資料庫伺服器也會吃不消 差異備份跟完全備份結合將是改善資料庫性能的一個不錯的策略
第四層 資料庫對象
若以上三個層面後 資料庫性能還不能夠得到大幅度改善的話 則就需要考慮是否能夠調整資料庫對象來完成我們的目的 雖然調整資料庫對象往往可以提到不錯的效果 但是 往往會對資料庫產生比較大的影響 所以 筆者一般不建議用戶一開始就通過調整資料庫對象來達到改善資料庫性能的目的
資料庫對象有表 視圖 索引 關鍵字等等 我們也可以通過對這些對象進行調整以實現改善資料庫性能的目標
如在視圖設計時 盡量把其顯示的內容縮小 寧可多增加視圖 如出貨明細表 銷售人員可能希望看到產品編號 產品中英文描述 產品名字 出貨日期 客戶編號 客戶名字等等 但是 對於財務來說 可能就不需要這么全的信息 他們只需要產品編號 客戶編號 出貨日期等等少量的信息即可 所以 能可浪費一點代碼的空間 設計兩張視圖 對應不同部門的需求 如此 財務部門在查詢數據時 不會為不必要的數據浪費寶貴的資源
如可以通過合理設置索引來提高資料庫的性能 索引對於提高數據的查詢效率 有著非常好的效果 對一些需要重復查詢的數據 或者數據修改不怎麼多的表設置索引 無疑是一個不錯的選擇
另外 要慎用存儲過程 雖然說存儲過程可以幫助大家實現很多需求 但是 在萬不得已的情況下 不要使用存儲過程 而利用前台的應用程序來實現需求 這主要是因為在通常情況下 前台應用程序的執行效率往往比後台資料庫存儲過程要高的多
第五層 SQL 語句
若以上各個層面你都努力過 但是還不滿足由此帶來的效果的話 則還有最後一招 通過對SQL語句進行優化 也可以達到改善資料庫性能的目的
雖然說SQL Server伺服器自身就帶有一個SQL語句優化器 他會對用戶的SQL語句進行調整 優化 以達到一個比較好的執行效果 但是 據筆者的了解 這個最多隻能夠優化一些粗略的層面 或者說 %的優化仍然需要資料庫管理員的配合 要資料庫管理員跟SQL優化器進行配合 才能夠起到非常明顯的作用
不過 SQL語句的調整對於普通資料庫管理員來說 可能有一定的難度 除非受過專業的訓練 一般很難對SQL語句進行優化 還好筆者受過這方面的專業訓練 對這方面有比較深的認識 如在SQL語句中避免使用直接量 任何一個包含有直接量的SQL語句都不太可能被再次使用 我們資料庫管理員要學會利用主機變數來代替直接量 不然 這些不可再用的查詢語句將使得程序緩存被不可再用的SQL語句填滿 這都是平時工作中的一些小習慣
lishixin/Article/program/SQLServer/201311/22452
❸ 資料庫MSSQL運行慢是什麼原因
(1) 可以考慮一下索引的問題
對在你的SQL語句中WHERE子句里涉及的列, 設置為索引列, 將極大提高你的訪問性能. 特別是頻繁訪問的表,更應該注意這個問題.
(2) 考慮存儲過程的使用
對經常訪問或連續操作的SQL語句,可以考慮放在存儲過程中處理, 由於存儲過程是預編譯的, 一般可以提高速度
(3) 考慮"事務"的問題
事務中的SQL語句,在提交前會鎖定相關的表,使其無法訪問,直到提交為止
(4) 考慮你的連接方式, 是否用到了連接池, 一般連接池的合理使用會提高你的速度及程序的可用性.
❹ sqlserver 資料庫服務突然緩慢 重啟後正常 運行的sql只有30多條
沒有用到索引或者就是內存小了,因為沒有備份運行時有的sql丟失了。
看看資料庫內存設置是否比較小,資料庫表是否建立合理的索引。
因為主機長期在工作.數據會一上在增多..對於內存還有CPU來說不是所有數據都可以一次性的完全處理好。就會有一些"尾數"包括記錄,然而越來越多,會讓主機運行速度變慢。如果用好點的專用的伺服器硬碟,內存會讓主機更長時間的不用重啟。所以SQL還是要用高一點的配置。
❺ 如何解決SQL Server資料庫查詢速度慢
�緯閃似烤斃вΑ� 3、沒有創建計算列導致查詢不優化。 4、內存不足5、網路速度慢6、查詢出的數據量過大(可以採用多次查詢,其他的方法降低數據量) 7、鎖或者死鎖(這也是查詢慢最常見的問題,是程序設計的缺陷) 8、sp_lock,sp_who,活動的用戶查看,原因是讀寫競爭資源。 9、返回了不必要的行和列10、查詢語句不好,沒有優化 可以通過以下方法來優化查詢 : 1、把數據、日誌、索引放到不同的I/O設備上,增加讀取速度,以前可以將Tempdb應放在RAID0上,SQL2000不在支持。數據量(尺寸)越大,提高I/O越重要。 2、縱向、橫向分割表,減少表的尺寸(sp_spaceuse) 3、升級硬體 4、根據查詢條件,建立索引,優化索引、優化訪問方式,限制結果集的數據量。注意填充因子要適當(最好是使用默認值0)。索引應該盡量小,使用位元組數小的列建索引好(參照索引的創建),不要對有限的幾個值的欄位建單一索引如性別欄位。 5、提高網速。 6、擴大伺服器的內存,Windows 2000和SQL server 2000能支持4-8G的內存。 配置虛擬內存:虛擬內存大小應基於計算機上並發運行的服務進行配置。運行 Microsoft SQL Server? 2000時,可考慮將虛擬內存大小設置為計算機中安裝的物理內存的1.5倍。如果另外安裝了全文檢索功能,並打算運行Microsoft搜索服務以便執行全文索引和查詢,可考慮:將虛擬內存大小配置為至少是計算機中安裝的物理內存的3倍。將SQL Server max server memory伺服器配置選項配置為物理內存的1.5倍(虛擬內存大小設置的一半)。 7、增加伺服器CPU個數;但是必須 明白並行處理串列處理更需要資源例如內存。使用並行還是串列程是MsSQL自動評估選擇的。單個任務分解成多個任務,就可以在處理器上運行。例如耽擱查詢 的排序、連接、掃描和GROUP BY字句同時執行,SQL SERVER根據系統的負載情況決定最優的並行等級,復雜的需要消耗大量的CPU的查詢最適合並行處理。但是更新操作UPDATE,INSERT, DELETE還不能並行處理。 8、如果是使用like進行查詢的話,簡單的使用index是不行的,但是全文索引,耗空間。 like ''a%'' 使用索引 like ''%a'' 不使用索引用 like ''%a%'' 查詢時,查詢耗時和欄位值總長度成正比,所以不能用CHAR類型,而是VARCHAR.對於欄位的值很長的建全文索引。 9、DB Server 和APPLication Server 分離;OLTP和OLAP分離 10、分布式分區視圖可用於實現資料庫伺服器聯合體。 聯合體是一組分開管理的伺服器,但它們相互協作分擔系統的處理負荷。這種通過分區數據形成資料庫伺服器聯合體的機制能夠擴大一組伺服器,以支持大型的多層 Web 站點的處理需要。有關更多信息,參見設計聯合資料庫伺服器。(參照SQL幫助文件''分區視圖'') a、在實現分區視圖之前,必須先水平分區表 b、在創建成員表後,在每個成員伺服器上定義一個分布式分區視圖,並且每個視圖具有相同的名稱。這樣,引用分布式分區視圖名的查詢可以在任何一個成員伺服器上 運行。系統操作如同每個成員伺服器上都有一個原始表的復本一樣,但其實每個伺服器上只有一個成員表和一個分布式分區視圖。數據的位置對應用程序是透明的。 11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收縮數據和日誌 DBCC SHRINKDB,DBCC SHRINKFILE. 設置自動收縮日誌。對於大的資料庫不要設置資料庫自動增長,它會降低伺服器的性能。 在T-sql的寫法上有很大的講究,下面列出常見的要點:首先,DBMS處理查詢計劃的過程是這樣的: 1、 查詢語句的詞法、語法檢查2、 將語句提交給DBMS的查詢優化器3、 優化器做代數優化和存取路徑的優化4、 由預編譯模塊生成查詢規劃5、 然後在合適的時間提交給系統處理執行6、 最後將執行結果返回給用戶。 其次,看一下SQL SERVER的數據存放的結構:一個頁面的大小為8K(8060)位元組,8個頁面為一個盤區,按照B樹存放。 12、 Commit和rollback的區別 Rollback:回滾所有的事物。 Commit:提交當前的事物。 沒有必要在動態SQL里寫事物,如果要寫請寫在外面如: begin tran exec(@s) commit trans 或者將動態SQL 寫成函數或者存儲過程。 13、在查詢Select語句中用Where字句限制返回的行數,避免表掃描,如果返回不必要的數據,浪費了伺服器的I/O資源,加重了網路的負擔降低性能。如果表很大,在表掃描的期間將表鎖住,禁止其他的聯接訪問表,後果嚴重。 14、SQL的注釋申明對執行沒有任何影響 15、盡可能不使用游標,它佔用大量的資源。如果需要row-by-row地執行,盡量採用非游標技術,如:在客戶端循環,用臨時表,Table變數,用子查詢,用Case語句等等。 游標可以按照它所支持的提取選項進行分類:只進必須按照從第一行到最後一行的順序提取行。FETCH NEXT 是唯一允許的提取操作,也是默認方式。可滾動性可以在游標中任何地方隨機提取任意行。游標的技術在SQL2000下變得功能很強大,他的目的是支持循環。 有四個並發選項 READ_ONLY:不允許通過游標定位更新(Update),且在組成結果集的行中沒有鎖。 OPTIMISTIC WITH valueS:樂觀並發控制是事務控制理論的一個標准部分。樂觀並發控制用於這樣的情形,即在打開游標及更新行的間隔中,只有很小的機會讓第二個用戶更新某一行。當某個游標以此選項打開時,沒有鎖控制其中的行,這將有助於最大化其處理能力。如果用戶試圖修改某一行,則此行的當前值會與最後一次提取此行時獲取的值進行比較。如果任何值發生改變,則伺服器就會知道其他人已更新了此行,並會返回一個錯誤。如果值是一樣的,伺服器就執行修改。 選擇這個並發選項OPTIMISTIC WITH ROW VERSIONING:此樂觀並發控制選項基於行版本控制。使用行版本控制,其中的表必須具有某種版本標識符,伺服器可用它來確定該行在讀入游標後是否有 所更改。在SQL Server中,這個性能由timestamp數據類型提供,它是一個二進制數字,表示資料庫中更改的相對順序。 每個資料庫都有一個全局當前時間戳值:@@DBTS.每次以任何方式更改帶有 timestamp 列的行時,SQL Server 先在時間戳列中存儲當前的 @@DBTS 值,然後增加 @@DBTS 的值。如果某 個表具有 timestamp 列,則時間戳會被記到行級。伺服器就可以比較某行的當前時間戳值和上次提取時所存儲的時間戳值,從而確定該行是否已更新。伺服器不必比較所有列的值,只需 比較 timestamp 列即可。如果應用程序對沒有 timestamp 列的表要求基於行版本控制的樂觀並發,則游標默認為基於數值的樂觀並發控制。 SCROLL LOCKS 這個選項實現悲觀並發控制。在悲觀並發控制中,在把資料庫的行讀入游標結果集時,應用程序將試圖鎖定資料庫行。在使用伺服器游標時,將行讀入游標時會在其上放置一個更新鎖。如果在事務內打開游標,則該事務更新鎖將一直保持到事務被提交或回滾;當提取下一行時,將除去游標鎖。如果在事務外打開游標,則提取下一行時,鎖就被丟棄。 因此,每當用戶需要完全的悲觀並發控制時,游標都應在事務內打開。更新鎖將阻止任何其它任務獲取更新鎖或排它鎖,從而阻止其它任務更 新該行。然而,更新鎖並不阻止共享鎖,所以它不會阻止其它任務讀取行,除非第二個任務也在要求帶更新鎖的讀取。滾動鎖根據在游標定義的 SELECT 語句中指定的鎖提示,這些游標並發選項可以生成滾動鎖。滾動鎖在提取時在每行上獲取,並保持到下次提取或者游標關閉,以先發生者為准。下次提取時,伺服器為新提取中的行獲取滾動鎖,並釋放上次提取中行的滾動鎖。滾動鎖獨立於事務鎖,並可以保持到一個提交或回滾操作之後。如果提交時關閉游標的選項為關,則COMMIT語句並不關閉任何打開的游標,而且滾動鎖被保留到提交之後,以維護對所提取數據的隔離。所獲取滾動鎖的類型取決於游標並發選項和游標 SELECT 語句中的鎖提示。鎖提示 只讀樂觀數值 指定NOLOCK 提示將使指定了該提示的表在游標內是只讀的。 16、用Profiler來跟蹤查詢,得到查詢所需的時間,找出SQL的問題所在;用索引優化器優化索引 17、注意UNion和UNion all 的區別。UNION all好 18、注意使用DISTINCT,在沒有必要時不要用,它同UNION一樣會使查詢變慢。重復的記錄在查詢里是沒有問題的 19、查詢時不要返回不需要的行、列 20、 用sp_configure ''query governor cost limit''或者SET QUERY_GOVERNOR_COST_LIMIT來限制查詢消耗的資源。當評估查詢消耗的資源超出限制時,伺服器自動取消查詢,在查詢之前就扼殺掉。 SET LOCKTIME設置鎖的時間 21、用select top 100 / 10 Percent 來限制用戶返回的行數或者SET ROWCOUNT來限制操作的行 22、 在SQL2000以前,一般不要用如下的字句: "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE ''%500''",因為他們不走索引全是表掃描。也不要在WHere字句中的列名加函數,如Convert,substring等,如果必須用函數的時 候,創建計算列再創建索引來替代。還可以變通寫法:WHERE SUBSTRING(firstname,1,1) = ''m''改為WHERE firstname like ''m%''(索引掃描),一定要將函數和列名分開。並且索引不能建得太多和太大。NOT IN會多次掃描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 來替代,特別是左連接,而Exists比IN更快,最慢的是NOT操作。如果列的值含有空,以前它的索引不起作用,現在2000的優化器能夠處理了。相同 的是IS NULL,「NOT", "NOT EXISTS", "NOT IN"能優化她,而」<>「等還是不能優化,用不到索引。 23、使用Query Analyzer,查看SQL語句的查詢計劃和評估分析是否是優化的SQL.一般的20%的代碼占據了80%的資源,我們優化的重點是這些慢的地方。 24、如果使用了IN或者OR等時發現查詢沒有走索引,使用顯示申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (『男』,『女』) 25、將需要查詢的結果預先計算好放在表中,查詢的時候再SELECT.這在SQL7.0以前是最重要的手段。例如醫院的住院費計算。 26、MIN() 和 MAX()能使用到合適的索引。 27、 資料庫有一個原則是代碼離數據越近越好,所以優先選擇Default,依次為Rules,Triggers, Constraint(約束如外健主健CheckUNIQUE……,數據類型的最大長度等等都是約束),Procere.這樣不僅維護工作小,編寫程 序質量高,並且執行的速度快。 28、如果要插入大的二進制值到Image列,使用存儲過程,千萬不要用內嵌INsert來插入(不知JAVA 是否)。因為這樣應用程序首先將二進制值轉換成字元串(尺寸是它的兩倍),伺服器受到字元後又將他轉換成二進制值。
❻ 如何解決SQL Server查詢速度緩慢的問題
優化SQL Server查詢速度的方法:
1、把數據、日誌、索引放到不同的I/O設備上,增加讀取速度,以前可以將Tempdb應放在RAID0上,SQL2000不在支持。數據量(尺寸)越大,提高I/O越重要.
2、縱向、橫向分割表,減少表的尺寸(sp_spaceuse)
3、升級硬體
4、根據查詢條件,建立索引,優化索引、優化訪問方式,限制結果集的數據量。注意填充因子要適當(最好是使用默認值0)。索引應該盡量小,使用位元組數小的列建索引好(參照索引的創建),不要對有限的幾個值的欄位建單一索引如性別欄位
5、提高網速;
6、擴大伺服器的內存,Windows 2000和SQL server 2000能支持4-8G的內存。
配置虛擬內存:虛擬內存大小應基於計算機上並發運行的服務進行配置。運行 Microsoft SQL Server? 2000 時,可考慮將虛擬內存大小設置為計算機中安裝的物理內存的 1.5 倍。如果另外安裝了全文檢索功能,並打算運行 Microsoft 搜索服務以便執行全文索引和查詢,可考慮:將虛擬內存大小配置為至少是計算機中安裝的物理內存的 3 倍。將 SQL Server max server memory 伺服器配置選項配置為物理內存的 1.5 倍(虛擬內存大小設置的一半)。
7、增加伺服器CPU個數;但是必須明白並行處理串列處理更需要資源例如內存。使用並行還是串列程是MsSQL自動評估選擇的。單個任務分解成多個任務,就可以在處理器上運行。例如耽擱查詢的排序、連接、掃描和GROUP BY字句同時執行,SQL SERVER根據系統的負載情況決定最優的並行等級,復雜的需要消耗大量的CPU的查詢最適合並行處理。但是更新操作UPDATE,INSERT, DELETE還不能並行處理。
8、如果是使用like進行查詢的話,簡單的使用index是不行的,但是全文索引,耗空間。 like ''a%'' 使用索引 like ''%a'' 不使用索引用 like ''%a%'' 查詢時,查詢耗時和欄位值總長度成正比,所以不能用CHAR類型,而是VARCHAR。對於欄位的值很長的建全文索引。
9、DB Server 和APPLication Server 分離;OLTP和OLAP分離
10、分布式分區視圖可用於實現資料庫伺服器聯合體。
聯合體是一組分開管理的伺服器,但它們相互協作分擔系統的處理負荷。這種通過分區數據形成資料庫伺服器聯合體的機制能夠擴大一組伺服器,以支持大型的多層 Web 站點的處理需要。有關更多信息,參見設計聯合資料庫伺服器。(參照SQL幫助文件''分區視圖'')
a、在實現分區視圖之前,必須先水平分區表
b、在創建成員表後,在每個成員伺服器上定義一個分布式分區視圖,並且每個視圖具有相同的名稱。這樣,引用分布式分區視圖名的查詢可以在任何一個成員伺服器上運行。系統操作如同每個成員伺服器上都有一個原始表的復本一樣,但其實每個伺服器上只有一個成員表和一個分布式分區視圖。數據的位置對應用程序是透明的。
11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收縮數據和日誌 DBCC SHRINKDB,DBCC SHRINKFILE.設置自動收縮日誌.對於大的資料庫不要設置資料庫自動增長,它會降低伺服器的性能。
在T-sql的寫法上有很大的講究,下面列出常見的要點:首先,DBMS處理查詢計劃的過程是這樣的:
1、查詢語句的詞法、語法檢查
2、將語句提交給DBMS的查詢優化器
3、優化器做代數優化和存取路徑的優化
4、由預編譯模塊生成查詢規劃
5、然後在合適的時間提交給系統處理執行
6、最後將執行結果返回給用戶。
其次,看一下SQL SERVER的數據存放的結構:一個頁面的大小為8K(8060)位元組,8個頁面為一個盤區,按照B樹存放。
12、 Commit和rollback的區別 Rollback:回滾所有的事物。 Commit:提交當前的事物.沒有必要在動態SQL里寫事物,如果要寫請寫在外面如: begin tran exec(@s) commit trans 或者將動態SQL 寫成函數或者存儲過程。
13、在查詢Select語句中用Where字句限制返回的行數,避免表掃描,如果返回不必要的數據,浪費了伺服器的I/O資源,加重了網路的負擔降低性能。如果表很大,在表掃描的期間將表鎖住,禁止其他的聯接訪問表,後果嚴重。
14、SQL的注釋申明對執行沒有任何影響
15、盡可能不使用游標,它佔用大量的資源。如果需要row-by-row地執行,盡量採用非游標技術,如:在客戶端循環,用臨時表,Table變數,用子查詢,用Case語句等等。游標可以按照它所支持的提取選項進行分類:只進必須按照從第一行到最後一行的順序提取行。FETCH NEXT 是唯一允許的提取操作,也是默認方式。可滾動性可以在游標中任何地方隨機提取任意行。游標的技術在SQL2000下變得功能很強大,他的目的是支持循環。有四個並發選項 READ_ONLY:不允許通過游標定位更新(Update),且在組成結果集的行中沒有鎖。 OPTIMISTIC WITH valueS:樂觀並發控制是事務控制理論的一個標准部分。樂觀並發控制用於這樣的情形,即在打開游標及更新行的間隔中,只有很小的機會讓第二個用戶更新某一行。當某個游標以此選項打開時,沒有鎖控制其中的行,這將有助於最大化其處理能力。如果用戶試圖修改某一行,則此行的當前值會與最後一次提取此行時獲取的值進行比較。如果任何值發生改變,則伺服器就會知道其他人已更新了此行,並會返回一個錯誤。如果值是一樣的,伺服器就執行修改。選擇這個並發選項?OPTIMISTIC WITH ROW VERSIONING:此樂觀並發控制選項基於行版本控制。使用行版本控制,其中的表必須具有某種版本標識符,伺服器可用它來確定該行在讀入游標後是否有所更改。在 SQL Server 中,這個性能由 timestamp 數據類型提供,它是一個二進制數字,表示資料庫中更改的相對順序。每個資料庫都有一個全局當前時間戳值:@@DBTS。每次以任何方式更改帶有 timestamp 列的行時,SQL Server 先在時間戳列中存儲當前的 @@DBTS 值,然後增加 @@DBTS 的值。如果某個表具有 timestamp 列,則時間戳會被記到行級。伺服器就可以比較某行的當前時間戳值和上次提取時所存儲的時間戳值,從而確定該行是否已更新。伺服器不必比較所有列的值,只需比較 timestamp 列即可。如果應用程序對沒有 timestamp 列的表要求基於行版本控制的樂觀並發,則游標默認為基於數值的樂觀並發控制。 SCROLL LOCKS 這個選項實現悲觀並發控制。在悲觀並發控制中,在把資料庫的行讀入游標結果集時,應用程序將試圖鎖定資料庫行。在使用伺服器游標時,將行讀入游標時會在其上放置一個更新鎖。如果在事務內打開游標,則該事務更新鎖將一直保持到事務被提交或回滾;當提取下一行時,將除去游標鎖。如果在事務外打開游標,則提取下一行時,鎖就被丟棄。因此,每當用戶需要完全的悲觀並發控制時,游標都應在事務內打開。更新鎖將阻止任何其它任務獲取更新鎖或排它鎖,從而阻止其它任務更新該行。然而,更新鎖並不阻止共享鎖,所以它不會阻止其它任務讀取行,除非第二個任務也在要求帶更新鎖的讀取。滾動鎖根據在游標定義的 SELECT 語句中指定的鎖提示,這些游標並發選項可以生成滾動鎖。滾動鎖在提取時在每行上獲取,並保持到下次提取或者游標關閉,以先發生者為准。下次提取時,伺服器為新提取中的行獲取滾動鎖,並釋放上次提取中行的滾動鎖。滾動鎖獨立於事務鎖,並可以保持到一個提交或回滾操作之後。如果提交時關閉游標的選項為關,則 COMMIT 語句並不關閉任何打開的游標,而且滾動鎖被保留到提交之後,以維護對所提取數據的隔離。所獲取滾動鎖的類型取決於游標並發選項和游標 SELECT 語句中的鎖提示。
16、用Profiler來跟蹤查詢,得到查詢所需的時間,找出SQL的問題所在;用索引優化器優化索引
17、注意UNion和UNion all 的區別。UNION all好
18、注意使用DISTINCT,在沒有必要時不要用,它同UNION一樣會使查詢變慢。重復的記錄在查詢里是沒有問題的
19、查詢時不要返回不需要的行、列
20、用sp_configure ''query governor cost limit''或者SET QUERY_GOVERNOR_COST_LIMIT來限制查詢消耗的資源。當評估查詢消耗的資源超出限制時,伺服器自動取消查詢,在查詢之前就扼殺掉。 SET LOCKTIME設置鎖的時間
21、用select top 100 / 10 Percent 來限制用戶返回的行數或者SET ROWCOUNT來限制操作的行
22、在SQL2000以前,一般不要用如下的字句
", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE ''%500''",因為他們不走索引全是表掃描。也不要在WHere字句中的列名加函數,如Convert,substring等,如果必須用函數的時候,創建計算列再創建索引來替代.還可以變通寫法:WHERE SUBSTRING(firstname,1,1)= ''m''改為WHERE firstname like ''m%''(索引掃描),一定要將函數和列名分開。並且索引不能建得太多和太大。NOT IN會多次掃描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 來替代,特別是左連接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,現在2000的優化器能夠處理了。相同的是IS NULL,「NOT", "NOT EXISTS", "NOT IN"能優化她,而」<>」等還是不能優化,用不到索引。
23、使用Query Analyzer,查看SQL語句的查詢計劃和評估分析是否是優化的SQL。一般的20%的代碼占據了80%的資源,我們優化的重點是這些慢的地方。
24、如果使用了IN或者OR等時發現查詢沒有走索引,使用顯示申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (『男』,『女』)
25、將需要查詢的結果預先計算好放在表中,查詢的時候再SELECT。這在SQL7.0以前是最重要的手段。例如醫院的住院費計算。
26、MIN()和 MAX()能使用到合適的索引。
27、資料庫有一個原則是代碼離數據越近越好,所以優先選擇Default,依次為Rules,Triggers, Constraint(約束如外健主健CheckUNIQUE……,數據類型的最大長度等等都是約束),Procere.這樣不僅維護工作小,編寫程序質量高,並且執行的速度快。
28、如果要插入大的二進制值到Image列,使用存儲過程,千萬不要用內嵌INsert來插入(不知JAVA 是否)。因為這樣應用程序首先將二進制值轉換成字元串(尺寸是它的兩倍),伺服器受到字元後又將他轉換成二進制值.存儲過程就沒有這些動作:方法:Create procere p_insert as insert into table(Fimage) values (@image),在前台調用這個存儲過程傳入二進制參數,這樣處理速度明顯改善。
❼ 當資料庫變慢時的解決方法有哪些
我們使用電腦和手機時候最不能忍受就是設備又卡又慢了,嚴重影響我們工作或者游戲體驗。當資料庫變慢時,我們應如何入手,下面的解決方法。
方法步驟
第一章 檢查系統的狀態
1.1 使用sar來檢查操作系統是否存在IO問題
1.2 關注內存vmstat
1.3 找到使用資源特別大的Oracle的session及其執行的語句
1.4 查找前十條性能差的sql語句
當資料庫變慢時,我們應如何入手
當應用管理員通告現在應用很慢、資料庫很慢時,當Oracle DBA在資料庫上做幾個示例的Select也發現同樣的問題時,有些時侯就會無從下手,因為DBA認為資料庫的各種命種率都是滿足Oracle文檔的建議。實際上如今的優化己經向優化等待(waits)轉型了,實際中性能優化最根本的出現點也都集中在I/O,這是影響性能最主要的方面,由系統中的等待去發現Oracle庫中的不足、操作系統某些資源利用的不合理是一個比較好的辦法。下面把一些實踐經驗與大家分享,本文測重於Unix環境。
第一章 檢查系統的狀態
通過操作系統的一些工具檢查系統的狀態,比如CPU、內存、交換、磁碟的利用率,根據經驗或與系統正常時的狀態相比對,有時系統表面上看起來看空閑,這也可能不是一個正常的狀態,因為cpu可能正等待IO的完成。除此之外,還應觀注那些佔用系統資源(cpu、內存)的進程。
1.1 使用sar來檢查操作系統是否存在IO問題
#sar -u 2 10 -- 即每隔2秒檢察一次,共執行20次。
結果示例:
註:在redhat下,%system就是所謂的%wio。
Linux 2.4.21-20.ELsmp (YY075) 05/19/2005
10:36:07 AM CPU %user %nice %system %idle
10:36:09 AM all 0.00 0.00 0.13 99.87
10:36:11 AM all 0.00 0.00 0.00 100.00
10:36:13 AM all 0.25 0.00 0.25 99.49
10:36:15 AM all 0.13 0.00 0.13 99.75
10:36:17 AM all 0.00 0.00 0.00 100.00
其中:
Ø %usr指的是用戶進程使用的cpu資源的百分比;
Ø %sys指的是系統資源使用cpu資源的百分比;
Ø %wio指的是等待io完成的百分比,這是值得觀注的一項;
Ø %idle即空閑的百分比。
如果wio列的值很大,如在35%以上,說明系統的IO存在瓶頸,CPU花費了很大的時間去等待I/O的完成。Idle很小說明系統CPU很忙。像以上的示例,可以看到wio平均值為11,說明I/O沒什麼特別的問題,而idle值為零,說明cpu已經滿負荷運行了。
當系統存在IO問題時,可以從以下幾個方面解決:
Ø 聯系相應的操作系統的技術支持對這方面進行優化,比如hp-ux在劃定卷組時的條帶化等方面。
Ø 查找Oracle中不合理的sql語句,對其進行優化;
Ø 對Oracle中訪問量頻繁的表除合理建索引外,再就是把這些表分表空間存放以免訪問上產生熱點,再有就是對表合理分區。
1.2 關注內存
常用的工具便是vmstat,對於hp-unix來說,可以用glance。Aix來說可以用topas。當發現vmstat中pi列非零,memory中的free列的值很小,glance、topas中內存的利用率多於80%時,這時說明內存方面應該調節一下。方法大體有以下幾項:
Ø 劃給Oracle使用的內存不要超過系統內存的1/2,一般保在系統內存的40%為益。
Ø 為系統增加內存;
Ø 如果你的連接特別多,可以使用MTS的方式;
Ø 打全補丁,防止內存漏洞。
1.3 找到使用資源特別大的Oracle的session及其執行的語句
Hp-unix可以用glance或top。IBM AIX可以用topas。此外可以使用ps的命令。
通過這些程序可以找到點用系統資源特別大的這些進程的進程號,就可以通過以下的sql語句發現這個pid正在執行哪個sql,這個sql最好在pl/sql developer、toad等軟體中執行:
SELECT a.username, a.machine, a.program, a.sid, a.serial#, a.status,
c.piece, c.sql_text
FROM v$session a, v$process b, v$sqltext c
WHERE b.spid = 'ORCL'
AND b.addr = a.paddr
AND a.sql_address = c.address(+)
ORDER BY c.piece;
可以把得到的這個sql分析一下,看一下它的執行計劃是否走索引。對其優化避免全表掃描,以減少IO等待,從而加快語句的執行速度。
提示:在做優化sql時,經常碰到使用in的語句,這時一定要用exists把它給換掉,因為Oracle在處理In時是按Or的方式做的,即使使用了索引也會很慢。比如:
SELECT col1, col2, col3 FROM table1 a
WHERE a.col1 NOT IN (SELECT col1 FROM table2)
可以換成:
SELECT col1, col2, col3 FROM table1 a
WHERE NOT EXISTS
(SELECT 'x' FROM table2 b WHERE a.col1=b.col1)
1.4 查找前十條性能差的sql語句
SELECT * FROM (SELECT parsing_user_id, executions, sorts, command_type,
disk_reads, sql_text FROM v$sqlarea
ORDER BY disk_reads DESC)
WHERE ROWNUM<10;
第二章 檢查會話狀態
要快速發現Oracle Server的性能問題的原因,可以求助於v$session_wait視圖,看系統的這些session在等什麼,使用了多少的IO。以下是參考腳本:
-- 腳本說明:查看佔I/O較大的正在運行的session:
SELECT se.sid, se.serial#, pr.spid, se.username, se.status, se.terminal,
se.program, se.mole, se.sql_address, st.event, st.p1text,
si.physical_reads, si.block_changes
FROM v$session se, v$session_wait st, v$sess_io si, v$process pr
WHERE st.sid=se.sid AND st.sid=si.sid
AND se.PADDR=pr.ADDR
AND se.sid>6
AND st.wait_time=0
AND st.event NOT LIKE '%SQL%'
ORDER BY physical_reads DESC;
對檢索出的結果的幾點說明:
1. 以上是按每個正在等待的session已經發生的物理讀排的序,因為它與實際的I/O相關。
2. 可以看一下這些等待的進程都在忙什麼,語句是否合理?
SELECT sql_address FROM v$session WHERE sid=;
SELECT * FROM v$sqltext WHERE address=;
執行以上兩個語句便可以得到這個session的語句。
也以用alter system kill session 'sid, serial#';把這個session殺掉。
3. 應觀注一下event列,這是調優的關鍵一列,下面對常出現的event做以簡要的說明:
1) buffer busy waits,free buffer waits這兩個參數所標識是dbwr是否夠用的問題,與IO很大相關的,當v$session_wait中的free buffer wait的條目很小或沒有時,說明系統的dbwr進程決對夠用,不用調整;free buffer wait的條目很多,系統感覺起來一定很慢,這時說明dbwr已經不夠用了,它產生的wio已經成為資料庫性能的瓶頸,這時的解決辦法如下:
Ø 增加寫進程,同時要調整db_block_lru_latches參數:
示例:修改或添加如下兩個參數
db_writer_processes=4
db_block_lru_latches=8
Ø 開非同步IO。IBM這方面簡單得多,hp則麻煩一些,可以與Hp工程師聯系。
2) db file sequential read,指的是順序讀,即全表掃描,這也是應盡量減少的部分,解決方法就是使用索引、sql調優,同時可以增大db_file_multiblock_read_count這個參數。
3) db file scattered read參數指的是通過索引來讀取,同樣可以通過增加db_file_multiblock_read_count這個參數來提高性能。
4) latch free與栓相關,需要專門調節。
5) 其他參數可以不特別觀注
補充:解決系統變慢的常用技巧方法
1、在我的電腦窗口,右擊要清理的盤符―“屬性”―“清理磁碟”--勾選要刪除的文件--確定--是。
2、右鍵瀏覽器e――屬性――點2個刪除1個清除(都要逐一確定)――確定 。
3、把C:WINDOWSPrefetch(預讀文件)把裡面的文件全部刪除
4、用優化大師或超級兔子清理注冊表和垃圾文件。
5、“開始”――運行中輸入msconfig――確定――啟動――除了輸入法ctfmon以外的勾全去掉。
6、右鍵我的電腦”――屬性――點高級――點啟動和故障恢復中的設置――去掉所有的勾――寫入調試信息選擇“無”――確定――點高級下面錯誤報告――點禁用――2次確定。
7、“開始”..打開控制面板中的文件夾選項..點查看..點去末項自動搜索文件夾前面的勾..確定。
8、右鍵我的電腦――屬性――硬體――設備管理器――雙擊IDE控制器――次要通道――高級設置――傳送模式都選DMA――設備類型選無――確定――主要通道也同樣設置――確定。
9、右鍵C盤進行磁碟清理和其它選項中的系統還原清理。
❽ sql資料庫文件過大,程序運行非常慢,怎麼辦
收縮資料庫
一般情況下,SQL資料庫的收縮並不能很大程度上減小資料庫大小,其主要作用是收縮日誌大小,應當定期進行此操作以免資料庫日誌過大
1、設置資料庫模式為簡單模式:打開SQL企業管理器,在控制台根目錄中依次點開Microsoft SQL Server-->SQL Server組-->雙擊打開你的伺服器-->雙擊打開資料庫目錄-->選擇你的資料庫名稱(如論壇資料庫Forum)-->然後點擊右鍵選擇屬性-->選擇選項-->在故障還原的模式中選擇「簡單」,然後按確定保存
2、在當前資料庫上點右鍵,看所有任務中的收縮資料庫,一般裡面的默認設置不用調整,直接點確定
3、收縮資料庫完成後,建議將您的資料庫屬性重新設置為標准模式,操作方法同第一點,因為日誌在一些異常情況下往往是恢復資料庫的重要依據
❾ oracle資料庫運行sql很卡很慢很頓,看等待事件都是cursor:pin s on x,這是啥
詳解cursor: pin S wait on X等待事件 『cursor: pin * events』等待事件 該類等待事件一般是為了pin相關的子游標 『Cursor: pin S on X』 最常見的等待事件, 進程為了共享操作例如執行pin游標而以SHRD S mode申請mutex, 但是未立即獲得。原因是該游標被其他進程以EXCL X mode 持有了。 實際該 cursor: pin S wait on X等待事件往往是由於其他因素誘發的。Mutex爭用僅僅是問題的症狀,但根本原因需要Database Consultant 進一步挖掘。 下面我們列出一些已知的常見案例, 在這些例子中可以看到 我上面提到的 Mutex的爭用僅僅是偽爭用: 過多的子游標 High Version Counts 過多的子游標版本Version Count可能導致Mutex 爭用,一般一個SQL的Version Count不要高於500。 檢查High Version Count很簡單, 在AWR里就有SQL ordered by High Version Count,也可以寫SQL查V$SQL、V$SQLAREA 昂貴的X$、V$視圖查詢 一些對於V$、X$視圖的查詢,需要訪問X$KGL*之類的fixed table,可能觸發Mutex爭用。 Mutex持有者得不到CPU Mutex持有者若得不到足夠的CPU片可能一直阻塞他人,直到它拿到需要的CPU。 這種情況可能由於OS操作系統的實際情況或者使用Resource Manager而引起。需要配合AWR中的Host CPU、Instance CPu一起看。 已經被KILLED的SESSION仍持有Mutex 當session正持有Mutex,而其對應的Process被強制KILL掉, 則直到PMON徹底清理掉該Dead Process並釋放Mutex,其他session才能不再等待。 診斷該類問題,最好能檢查PMON的TRACE。 當然也存在部分BUG會導致PMON清理過程非常慢。 舉例來說,bug 9312879描述了一種場景:PMON 需要獲得某個Mutex以便清理某個dead process,但是該Mutex又被其他進程持有,則PMON甚至無法開始真正清理並釋放Mutex。 如果自己搞不定可以找ASKMACLEAN專業ORACLE優化團隊成員幫您搞定!