當前位置:首頁 » 編程語言 » sql執行超過300ms
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql執行超過300ms

發布時間: 2023-02-22 06:33:15

A. 如何執行超過一百兆的sql腳本

1、用記事本打開腳本文件,把文件依次剪切成10-15M左右的文本文件,然後再一個個執行;
2、或者在腳本導出時,分表導出,這樣導出的文本size也不會很大;
以上問題雖然簡便,但是步驟繁多,要是表和數據太多,著實是一種勞力折磨!另外如果表之間是有主外鍵關系的,分數據得小心謹慎,否則報錯讓你抓狂!

B. sql執行時間一般不超過多久

你好,一般是10-20毫秒。
擴展:
常見查詢慢的原因常見的話會有如下幾種:
1、沒有索引或沒有用到索引。
PS:索引用來快速地尋找那些具有特定值的記錄,所有MySQL索引都以B-樹的形式保存。如果沒有索引,執行查詢時MySQL必須從第一個記錄開始掃描整個表

的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜索條件的列上已經創建了索引,MySQL無需掃描任何記錄
即可迅速得到目標記錄所在的位置。如果表有1000個記錄,通過索引查找記錄至少要比順序掃描記錄快100倍。
索引類型:
普通索引:這是最基本的索引類型,沒唯一性之類的限制。
唯一性索引:和普通索引基本相同,但所有的索引列只能出現一次,保持唯一性。
主鍵:主鍵是一種唯一索引,但必須指定為"PRIMARY KEY"。
全文索引:MYSQL從3.23.23開始支持全文索引和全文檢索。在MYSQL中,全文索引的索引類型為FULLTEXT。全文索引可以在VARCHAR或者TEXT類型的列上創建。
2、IO吞吐量小形成了瓶頸。
PS:這是從系統層來分析MYSQL是比較耗IO的。一般資料庫監控也是比較關注IO。
監控命令:$iostat -d -k 1 10
參數 -d 表示,顯示設備(磁碟)使用狀態;-k某些使用block為單位的列強制使用Kilobytes為單位;1 10表示,數據顯示每隔1秒刷新一次,共顯示10次。

C. 如何能縮短sql語句的執行時間

1. SQL優化的原則是:將一次操作需要讀取的BLOCK數減到最低,即在最短的時間達到最大的數據吞吐量。
調整不良SQL通常可以從以下幾點切入:
? 檢查不良的SQL,考慮其寫法是否還有可優化內容
? 檢查子查詢 考慮SQL子查詢是否可以用簡單連接的方式進行重新書寫
? 檢查優化索引的使用
? 考慮資料庫的優化器

2. 避免出現SELECT * FROM table 語句,要明確查出的欄位。

3. 在一個SQL語句中,如果一個where條件過濾的資料庫記錄越多,定位越准確,則該where條件越應該前移。

4. 查詢時盡可能使用索引覆蓋。即對SELECT的欄位建立復合索引,這樣查詢時只進行索引掃描,不讀取數據塊。

5. 在判斷有無符合條件的記錄時建議不要用SELECT COUNT (*)和select top 1 語句。

6. 使用內層限定原則,在拼寫SQL語句時,將查詢條件分解、分類,並盡量在SQL語句的最里層進行限定,以減少數據的處理量。

7. 應絕對避免在order by子句中使用表達式。

8. 如果需要從關聯表讀數據,關聯的表一般不要超過7個。

9. 小心使用 IN 和 OR,需要注意In集合中的數據量。建議集合中的數據不超過200個。

10. <> 用 < 、 > 代替,>用>=代替,<用<=代替,這樣可以有效的利用索引。

11. 在查詢時盡量減少對多餘數據的讀取包括多餘的列與多餘的行。

12. 對於復合索引要注意,例如在建立復合索引時列的順序是F1,F2,F3,則在where或order by子句中這些欄位出現的順序要與建立索引時的欄位順序一致,且必須包含第一列。只能是F1或F1,F2或F1,F2,F3。否則不會用到該索引。

13. 多表關聯查詢時,寫法必須遵循以下原則,這樣做有利於建立索引,提高查詢效率。格式如下select sum(table1.je) from table1 table1, table2 table2, table3 table3 where (table1的等值條件(=)) and (table1的非等值條件) and (table2與table1的關聯條件) and (table2的等值條件) and (table2的非等值條件) and (table3與table2的關聯條件) and (table3的等值條件) and (table3的非等值條件)。
注:關於多表查詢時from 後面表的出現順序對效率的影響還有待研究。

14. 子查詢問題。對於能用連接方式或者視圖方式實現的功能,不要用子查詢。例如:select name from customer where customer_id in ( select customer_id from order where money>1000)。應該用如下語句代替:select name from customer inner join order on customer.customer_id=order.customer_id where order.money>100。

15. 在WHERE 子句中,避免對列的四則運算,特別是where 條件的左邊,嚴禁使用運算與函數對列進行處理。比如有些地方 substring 可以用like代替。

16. 如果在語句中有not in(in)操作,應考慮用not exists(exists)來重寫,最好的辦法是使用外連接實現。

17. 對一個業務過程的處理,應該使事物的開始與結束之間的時間間隔越短越好,原則上做到資料庫的讀操作在前面完成,資料庫寫操作在後面完成,避免交叉。

18. 請小心不要對過多的列使用列函數和order by,group by等,謹慎使用disti軟體開發t。

19. 用union all 代替 union,資料庫執行union操作,首先先分別執行union兩端的查詢,將其放在臨時表中,然後在對其進行排序,過濾重復的記錄。
當已知的業務邏輯決定query A和query B中不會有重復記錄時,應該用union all代替union,以提高查詢效率。

數據更新的效率
1. 在一個事物中,對同一個表的多個insert語句應該集中在一起執行。
2. 在一個業務過程中,盡量的使insert,update,delete語句在業務結束前執行,以減少死鎖的可能性。

資料庫物理規劃的效率

為了避免I/O的沖突,我們在設計資料庫物理規劃時應該遵循幾條基本的原則(以ORACLE舉例):
?? table和index分離:table和index應該分別放在不同的tablespace中。

?? Rollback Segment的分離:Rollback Segment應該放在獨立的Tablespace中。

?? System Tablespace的分離:System Tablespace中不允許放置任何用戶的object。(mssql中primary filegroup中不允許放置任何用戶的object)

?? Temp Tablesace的分離:建立單獨的Temp Tablespace,並為每個user指定default Temp Tablespace

??避免碎片:但segment中出現大量的碎片時,會導致讀數據時需要訪問的block數量的增加。對經常發生DML操作的segemeng來說,碎片是不能完全避免的。所以,我們應該將經常做DML操作的表和很少發生變化的表分離在不同的Tablespace中。

當我們遵循了以上原則後,仍然發現有I/O沖突存在,我們可以用數據分離的方法來解決。
?? 連接Table的分離:在實際應用中經常做連接查詢的Table,可以將其分離在不同的Taclespace中,以減少I/O沖突。

?? 使用分區:對數據量很大的Table和Index使用分區,放在不同的Tablespace中。

在實際的物理存儲中,建議使用RAID。日誌文件應放在單獨的磁碟中。

D. using index; using where

建表

線上表50w行

線上表當前索引:

主鍵索引、pc_id+process_sku_id組合索引、process_sku_id單獨索引

慢sql語句如下,執行時間平均300ms,低於公司標准100ms,故需優化

子查詢用到process_sku_id單獨索引,主查詢用到pc_id+process_sku_id組合索引,綜上,建立process_sku_id + pc_id組合索引即可替代原先的兩個索引;

SELECT * FROM `process_sku_overflow` ORDER BY `id` DESC LIMIT ?主鍵索引排序,效率沒問題

SELECT `pc_id`, `pc_name`, `process_date`, `process_sku_id`, `process_sku_name` , `category?_name`, `category?_name`, `category?_name`, `category?_name`, `actual_overflow_rate` FROM process_sku_overflow WHERE ? = ?where 1=2,瞬間返回,不涉及數據檢索,效率很高

綜上,考慮兩種方案:

1.process_sku_id+process_date+pc_id聯合索引 +刪除現有的pc_id+process_sku_id索引

2.process_sku_id+process_date+pc_id+ actual_overflow_rate覆蓋索引 +刪除現有的pc_id+process_sku_id索引

以及考慮是否可以刪除原索引,暫時先新增,目前表數據量50w較少,索引三個倒是也不用細究去刪除,穩妥起見先並存,後續如果表數據量過多(千萬級別),考慮刪除process_sku_id單獨索引單獨索引;

採用方案二建立覆蓋索引後,子查詢直接索引覆蓋,主查詢也在索引下推的幫助下實現了索引覆蓋,性能提升

下面是過程的一些學習感悟記錄,由於多次修改sql條件去測試Extra,故後續sql的explain結果均以**選中部分**執行,請勿認為每次都是執行的全部sql字句;

case1:匹配上索引,但是select 的欄位不被索引覆蓋

Extra信息為NULL,表示該查詢只需通過索引匹配即完成了整個篩選過程,但是索引並沒有包含需查詢的所有欄位,因此還需回表查詢;

case1.1 在上一個sql語句中,將process_sku_id in括弧里的數據增加到3個,成為范圍查詢

此時出現using index condition,即ICP,原因是此時引擎層會主動做索引下推過濾後回表查詢數據給到server層用戶,無需因為遇到范圍查詢而僅僅匹配pc_id後直接回表拿數據給server層過濾process_sku_id,減少引擎層返回過多的回表數據給到server層,「下推」其實是指原本需要在server層的過濾放到了引擎層;想了解ICP詳情可以參考https://blog.csdn.net/b1303110335/article/details/105831083、https://blog.csdn.net/meser88/article/details/120953207或者網路搜「mysql 索引下推」;

case 2:如果select只查詢pc_id和process_sku_id,即所需的欄位都在索引中

此時應該由於索引覆蓋的緣故,無需回表,直接using index;然而出現了using index; using where。各方查詢,這是由於雖然索引已經覆蓋了所有的欄位無需回表,但此處的using where跟using index同時出現表示的是雖然索引覆蓋了但在使用索引過濾時存在范圍查詢或者like匹配,在索引層面也經歷了類似where條件的匹配,若是沒有in的范圍查詢,則Extra顯示索引覆蓋;

case3:此時若在where條件中加入process_date欄位,則當前索引無法覆蓋需回表,則此時在索引層面由於范圍查詢先過濾了一下,屬於using index condition,再回表查詢去過濾process_date條件,因此還會有using where;

E. sql語句執行效率低,有上千萬條數據,耗時3分鍾

not in內外表都進行全表掃描,沒有用到索引,所以很慢not extsts 的子查詢能用到表上的索引。 改成:
select convert(varchar(10),scanTime,20) as 'DList' from T_SCAN
where not extsts
(
select 1 from T_Scan_image ts,T_SCAN t
where ts.scanTime = t.scanTime
)
group by convert (varchar(10),scanTime,20)

F. sybase資料庫中5000筆的insert耗時單筆300ms,如何sql調優

將絕大部分的SQL查詢改為存儲過程,這樣的操作毫無疑問可以提高部分性能。
凡是使用「select * from xxx」的操作一律具體到所需欄位。

使用join連接2個以上大量數據的表,且基礎數據表變化不大的查詢一律使用視圖,並為此視圖建立索引。理由來自SQL Server聯機幫助手冊:
「對於標准視圖而言,為每個引用視圖的查詢動態生成結果集的開銷很大,特別是對於那些涉及對大量行進行復雜處理(如聚合大量數據或聯接許多行)的視圖。如果在查詢中頻繁地引用這類視圖,可通過對視圖創建唯一聚集索引來提高性能。對視圖創建唯一聚集索引後,結果集將存儲在資料庫中,就像帶有聚集索引的表一樣。

G. 如何解決SQL查詢速度太慢

1. 執行計劃中明明有使用到索引,為什麼執行還是這么慢?

2. 執行計劃中顯示掃描行數為 644,為什麼 slow log 中顯示 100 多萬行?
a. 我們先看執行計劃,選擇的索引 「INDX_BIOM_ELOCK_TASK3(TASK_ID)」。結合 sql 來看,因為有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能會更差,優化器選擇這個索引避免了排序。
那為什麼不選 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很簡單,TASK_DATE 欄位區分度太低了,走這個索引需要掃描的行數很大,而且還要進行額外的排序,優化器綜合判斷代價更大,所以就不選這個索引了。不過如果我們強制選擇這個索引(用 force index 語法),會看到 SQL 執行速度更快少於 10s,那是因為優化器基於代價的原則並不等價於執行速度的快慢;
b. 再看執行計劃中的 type:index,"index" 代表 「全索引掃描」,其實和全表掃描差不多,只是掃描的時候是按照索引次序進行而不是行,主要優點就是避免了排序,但是開銷仍然非常大。
Extra:Using where 也意味著掃描完索引後還需要回表進行篩選。一般來說,得保證 type 至少達到 range 級別,最好能達到 ref。
在第 2 點中提到的「慢日誌記錄Rows_examined: 1161559,看起來是全表掃描」,這里更正為「全索引掃描」,掃描行數確實等於表的行數;
c. 關於執行計劃中:「rows:644」,其實這個只是估算值,並不準確,我們分析慢 SQL 時判斷准確的掃描行數應該以 slow log 中的 Rows_examined 為准。
4. 優化建議:添加組合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)

優化過程:
TASK_DATE 欄位存在索引,但是選擇度很低,優化器不會走這個索引,建議後續可以刪除這個索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+

在這個 sql 中 REL_DEVID 欄位從命名上看選擇度較高,通過下面 sql 來檢驗確實如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+

由於有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 組合選擇度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+

在測試環境添加 REL_DEVID,TASK_ID 組合索引,測試 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引後執行計劃:
這里還要注意一點「隱式轉換」:REL_DEVID 欄位數據類型為 varchar,需要在 sql 中加引號:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'

執行時間從 10s+ 降到 毫秒級別:
1 row in set (0.00 sec)
結論
一個典型的 order by 查詢的優化,添加更合適的索引可以避免性能問題:執行計劃使用索引並不意味著就能執行快。

H. 如何提高sql語句的執行效率

1、使用ordered提示

Oracle必須花費大量的時間來剖析多表的合並,用以確定表合並的最佳順序。SQL表達式涉及七個乃至更多的表合並,那麼有時就會需要超過30分鍾的時間來剖析,Ordered這個提示(hint)和其他的提示一起使用能夠產生合適的合並順序。

2、使用ordered_predicates

ordered_predicates提示在查詢的WHERE子句里指定的,並被用來指定布爾判斷(Booleanpredicate)被評估的順序。在沒有ordered_predicates的情況下,Oracle會使用下面這些步驟來評估SQL判斷的順序:子查詢的評估先於外層WHERE子句里的Boolean條件。

所有沒有內置函數或者子查詢的布爾條件都按照其在WHERE子句里相反的順序進行評估,即最後一條判斷最先被評估。每個判斷都帶有內置函數的布爾判斷都依據其預計的評估值按遞增排列。

3、限製表格合並評估的數量

提高SQL剖析性能的最後一種方法是強製取代Oracle的一個參數,這個參數控制著在評估一個查詢的時候,基於消耗的優化器所評估的可能合並數量。

(8)sql執行超過300ms擴展閱讀:

1、表設計的優化,數據行的長度不要超過8020位元組,如果超過這個長度的話在物理頁中這條數據會佔用兩行從而造成存儲碎片,降低查詢效率。

2、語句的查詢優化,保證在實現功能的基礎上,盡量減少對資料庫的訪問次數;

3、建立高效的索引創建索引一般有以下兩個目的:維護被索引列的唯一性和提供快速訪問表中數據的策略。

大型資料庫有兩種索引即簇索引和非簇索引,一個沒有簇索引的表是按堆結構存儲數據,所有的數據均添加在表的尾部,而建立了簇索引的表,其數據在物理上會按照簇索引鍵的順序存儲。個表只允許有一個簇索引。

4、強制查詢轉換,有時候oracle 的優化器未必能走正確的查詢路線,這個時候就需要添加一些hint 之類的來規定他的執行路線。當然了,這個未必是最好的處理方案。因為雖然現在走這個路線是對的,以為因為數據的變化到這這個HINT 變得不可取。

I. 如何執行超過一百兆的sql腳本

使用osql執行一個大腳本文件
將該工具指向一個腳本文件,步驟:

a.創建一個包含一批 Transact-SQL 語句的腳本文件(如 myfile.sql)。

b.打開命令提示符,鍵入與下面類似的一個命令,然後按 ENTER 鍵:

osql -E -i input_file

其中input_file 是腳本文件及其完整路徑。例如,如果腳本文件 myfile.sql 在 C:\users文件夾中,

請將參數 myfile 替換為 C:\users\myfile.sql。

該腳本文件的運行結果將出現在控制台窗口中。

如果您想將運行結果定向到一個文件,請向上述命令中添加 -o output_file 參數。例如:

osql -E -i input_file -o output_file

其中output_file 是輸出文件及其完整路徑。

J. 100ms的SQL把伺服器搞崩潰了

一個項目上線了兩個月,除了一些反饋的優化和小Bug之外,項目一切順利;前期是屬於推廣階段,可能使用人員沒那麼多,當然對於項目部署肯定提前想到並發量了,所以早就把集群安排上,而且還在測試環境搞了一下壓測,絕對是沒得問題的;但是,就在兩個月後的一天,系統突然跑的比烏龜還慢,投訴開始就陸續反饋過來了。

經過排查,原來是頻繁執行一條耗時100ms的SQL導致,100ms感覺不長,但就是把系統搞崩了,具體細節如下。

項目採用ABP進行開發,集成統一的認證中心(IDS4),部分數據對接第三方系統,拆分後的這個項目架構相對簡單。

考慮並發量不高,就算是高峰期也不會超過1000,於是就搞了個單台的資料庫伺服器(MySQL),測試環境中經過壓測,完全能抗住。

上線時,由於線上資源的關系,DB伺服器的配置沒有按測試環境的標准來分配,相關人員想著後續看情況進行補配。上線推的比較緊,簡單評估了配置風險,初步判斷沒啥大問題,於是就推上線了。

相關技術棧:ABP、IdentityServer4、Autofac、AutoMapper、Quartz.NET、EF Core、Redis、MySQL等,這都不重要,重要的是100ms的SQL把系統搞崩了。

由於系統相對不大,並沒有把分布式日誌、調度監控,性能監控集成上去。

上線期間,前期處於使用推廣階段,一切正常。兩個月後的一天,系統處於使用高峰時段,突然陸續收到反饋:系統有點卡!!!於是趕緊進行排查。

由於系統已經是集群部署的,慢這個問題首先懷疑是資料庫伺服器,於是讓DBA的同事排查了一下,沒有鎖,只是有大量事務等待提交(waiting for handler commit),通過如下命令可查的:

看到都是插入審計日誌記錄導致,一看日誌記錄頻率,差不多一秒500條記錄。DBA同事說可能是記錄插入頻繁導致,此時CPU已經爆到100%了,為了快速解決問題,於是就趕緊關掉了一些不必要的日誌記錄。

這么一改,稍微降了一點,沒有事務提交的記錄,系統勉強可以撐著用,但是CPU還是在85%~97%波動;

看到這種情況,當然還是不放心,繼續排查。 中間有對伺服器的配置產生過懷疑,但非常肯定的是這不是主要原因,於是和DBA的同事繼續排查。

系統雖然可以正常使用,但時不時的也看看監控屏,CPU一直處於高水位狀態,還是有點慌的,因為一有問題,信息和電話都要爆。

突然DBA同事發現有一個單表查詢的SQL執行比較頻繁,於是單獨拿出來試了一下,查詢時間150ms左右,這個表的數據量不大,8萬左右,但沒有加任何索引,因為想著數據量不大,查詢時長還可接受,所以當時就沒有加相關索引。

定位到這條SQL後,想到的第一步就是增加索引,在測試環境上試了一把,執行效率直接飛速提高到1ms;效果如下:

所以和DBA同事達成一致意見,在生成環境上增加復合索引( 創建索引一定要注意欄位順序 ),在中午時候,系統使用頻率不太高,於是就在生成上快速加了索引,我去,CPU一下降到了20%以內,意不意外;就算在使用高峰期,也沒超過20%,通過zabbix工具監控看到CPU的效果:

問題算是解決了,總算鬆了一口氣。

這里有個問題: CPU都爆了為什麼沒有報警提醒,這塊DBA同事正在排查相關配置。這里發現CPU爆了,還是無意的遠程到伺服器,發現很卡,一看CPU才知道爆了。

系統雖小,問題不大,但其實暴露的問題還是挺多。

這次線上小事故暫時分享到這,因為項目不大,所以沒有做那麼多監控,但以下建議,小夥伴可以參考一下:

文章來自https://www.cnblogs.com/zoe-zyq/p/16207287.html