當前位置:首頁 » 編程語言 » sql分批查詢
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql分批查詢

發布時間: 2023-08-27 22:22:07

A. sql怎麼控制檢索出的最大數據量,數量太大機器受不了,有能分批檢索的命令嗎

用分頁查詢演算法來實現。給你一個我寫的通用分頁存儲過程,將這個存儲過程創建在你的SQL資料庫上,調用該過程即可實現分頁查詢:

/*
通用存儲過程
只要傳入頁碼,每頁大小,查詢的sql語句,排序方式(不需要order)即可
*/
CREATE Procere [sp_common_cuspage3]
(
@PageNo int, --當前查詢頁碼
@PageSize int, --每頁數量
@sql nvarchar(2000), --查詢的SQL語句
@order nvarchar(200), --排序方式,例如:ResID desc
@totalcount int out --返回當前查詢SQL的符合總條數
)
AS
Begin
declare @querysql nvarchar(2000)
declare @countsql nvarchar(2000)
declare @begin int
declare @end int
declare @totalPage int

--查詢符合條件的條目數
set @countsql = N'select @count = count(*) from ('+@sql + N')G0'
exec sp_executesql @countsql, N' @count int output ', @totalcount output

--計算總頁碼及糾正當前頁碼
set @totalPage = (@totalcount-1)/@PageSize +1
IF(@PageNo > @totalPage ) set @PageNo = @totalPage

--計算起止位置
set @begin = @PageSize * (@PageNo-1)
set @end = @PageSize * @PageNo +1

--組合出SQL進行查詢
set @querysql = N'select * from ('
set @querysql = @querysql + N' SELECT Row_Number() OVER(ORDER BY ' + @order + N' ) as RowID ,G0.* FROM ('
set @querysql = @querysql + @sql
set @querysql = @querysql + N' ) G0 ) G1'
set @querysql = @querysql + N' Where G1.RowID >' + CAST(@begin as nvarchar) + N' AND G1.RowID<'+CAST(@end as nvarchar)

--print @querysql
exec(@querysql)
End

B. 請教各位,如何分批獲取資料庫中數據

在有些業務場景中需要分批去取資料庫表中的全部數據來進行處理,最簡單的方法就是使用分頁查詢語句(偷懶以MySQL為例):

[sql] view plain print?
select * from datatable limit offset,amount

select * from datatable limit offset,amount

這里就會有一個問題,隨著offset值的越來越大,這條sql要掃描的表數據就會越來越多,因為要定位到offset這一行就需要掃描比offset小的所有行。顯然在一張大數據量的表中,去這樣做,性能就會出問題。為了避免這樣的情形出現,我們自然會想到使用索引來解決,比如使用自增序列id進行分批取:

[sql] view plain print?
select * from datatable where id >= start and id<start+batchCount

select * from datatable where id >= start and id<start+batchCount

這樣我們對id建索引,然後分批去取,顯然效果會高很多,但是如果自增序列由於刪除等操作變得不是連續,就會出現空執行和多執行的情況出現。要解決這個方法,我們就需要結合使用索引和分頁的優勢來處理:

[sql] view plain print?
select * from datatable where id >= start limit batchCount

select * from datatable where id >= start limit batchCount

然後每次取回來我們再計算出起始id值,再去取下一批數據。這樣就可以既避免了第一種不走索引,查詢性能低下的問題,又解決了第二種id不連續,導致取回來的數據量不穩定導致浪費的問題了。

C. sql語句是分批循環查詢,定義一個pno,這段代碼報錯,應該如何修改啊

Stringstr2="";
for(intpno=0;pno<3;pno++){
if(pno==0){
str2="select*from(selectrownumrowa,d.*from(selectssw.sms_id,ssw.phone_numberfromsms_send_waitsswleftjoinsms_send_receivessronssr.sms_id=ssw.sms_idwherenotexists(selectssrb.phone_numberfromsms_send_receive_blacklistssrbwheressrb.phone_number=ssw.phone_number)andssw.send_wait_timebetweensysdate-1andsysdate+1)dwhererownum<=pno*2)whererowa>(pno-1)*2"
}else{
str2=str2+"union"+"select*from(selectrownumrowa,d.*from(selectssw.sms_id,ssw.phone_numberfromsms_send_waitsswleftjoinsms_send_receivessronssr.sms_id=ssw.sms_idwherenotexists(selectssrb.phone_numberfromsms_send_receive_blacklistssrbwheressrb.phone_number=ssw.phone_number)andssw.send_wait_timebetweensysdate-1andsysdate+1)dwhererownum<=pno*2)whererowa>(pno-1)*2"
}
}
pstmt=conn.prepareStatement(str2);
ResultSetrs=pstmt.executeQuery();
//你要是想把sql語句拼起來,一次性執行了,就用上面的方法,要是不想或不會拼,可以把pstmt=conn.prepareStatement(str2);
ResultSetrs=pstmt.executeQuery();
寫到for循環裡面,每循環一次執行一次,都可以的!

D. sql in語句的性能問題

每個機票訂單含有多個票,用符合條件的訂單List,去查詢對應的票List。
兩張表的關聯方式是用一個特性的key關聯,其中包含,代理商區分標余啟喊志,訂單號,訂單類型等,是一個長度在30~50之間的varchar
遍歷list一條一條查的話,IO太多,顯然不合適旁檔。我們就想到用in來實現批量查詢

在beta測試時,庫中表裡只有一個月的數據,大約在1000萬左右,測試時沒有發現問題。
到了線上之後,發現查詢數據非常慢,兩萬左右的in條件,查詢起來,時間在10分鍾左右,顯然出現了慢查詢。
針對這個問題,做了幾個測試,看了下執行計劃,如下所示

事實上我們看到,在in語句中數據量不大的情況下,索引是有效的,不過這個數量已經是極限了。

下面是我的語句

這里在in裡麵包含了三萬條數據,索引實效了。

這里我們首先想到,強制使用索引會不會有所幫助如下

但是,事實上並沒有效果,這是結果

解下來我們分析一下,兩個問題,索引為什麼會失效
這個問題需要從兩個方面入手

1.索引區豎野分度
2.預計掃描行數
3.優化器的選擇

先看第一個,索引的區分度,經過隨機采樣,看著內容還是很高的。

預計掃描行數
預計掃描行數的話,如前兩圖所示,基本都走了全表掃描。

優化器的選擇
優化器選擇時,衡量了回表等操作,綜合考慮,這里沒有辦法繼續下去了,只能問到DBA了。

在數據表大時,索引負重較大,同樣的情況下,in語句裡面數據條數夠大時,索引會失效,可以通過force index嘗試一下,不過成功的可能行很小,盡量分批去查找,批次數量可配置。

E. SQL項目列表中的列數超過655時,結果查看器無法執行查詢怎麼解決

那就分批來呀,按他們的主鍵排列,確保查詢出來的順序是一致的,然後查詢你需要顯示的列名,剩下的放在第二批查,分別把他們復制粘貼出來就好。

F. (問題解決再追加100分)sql server存儲過程實現查詢數據條數過大,分頁查詢怎麼實現

按說5-8w這樣數量級的數據沒有問題,寫入Excel是布比較耗性能,主要還是要通過優化寫入Excel的代碼效率上去考慮。你可以考慮利用分批查詢寫入的方式來避免一次寫太多的數據到Excel:將你的查詢結果分段,比方你的語句中能不能用時間來認為分段,每次返回部分結果。
回到你的問題,對大數據量查詢的解決方案有以下兩種:
(1)、將全部數據先查詢到內存中,然後在內存中進行分頁,這種方式對內存佔用較大,必須限制一次查詢的數據量。
(2)、採用存儲過程在資料庫中進行分頁,這種方式對資料庫的依賴較大,不同的資料庫實現機制不通,並且查詢效率不夠理想。以上兩種方式對用戶來說都不夠友好。

2.解決思路
通過在待查詢的資料庫表上增加一個用於查詢的自增長欄位,然後採用該欄位進行分頁查詢,可以很好地解決這個問題。下面舉例說明這種分頁查詢方案。

(1)、在待查詢的表格上增加一個long型的自增長列,取名為「queryId」,mssql、sybase直接支持自增長欄位,oracle可以用sequence和trigger來實現。然後在該列上加上一個索引。
添加queryId列的語句如下:
Mssql: [QUERYID] [bigint] IDENTITY (1, 1)

Sybase: QUERYID numeric(19) identity

Oracle:
CREATE SEQUENCE queryId_S
INCREMENT BY 1
START WITH 1
MAXVALUE 999999999999999 MINVALUE 1
CYCLE
CACHE 20
ORDER;
CREATE OR REPLACE TRIGGER queryId_T BEFORE INSERT
ON "test_table"
FOR EACH ROW
BEGIN
select queryId_S.nextval into :new.queryId from al;
END;

(2)、在查詢第一頁時,先按照大小順序的倒序查出所有的queryId,
語句如下:select queryId from test_table where + 查詢條件 +order by queryId desc 。
因為只是查詢queryId欄位,即使表格中的數據量很大,該查詢也會很快得到結果。然後將得到的queryId保存在應用伺服器的一個數組中。

(3)、用戶在客戶端進行翻頁操作時,客戶端將待查詢的頁號作為參數傳遞給應用伺服器,伺服器通過頁號和queyId數組算出待查詢的queyId最大和最小值,然後進行查詢。

算出queyId最大和最小值的演算法如下,其中page為待查詢的頁號,pageSize為每頁的大小,queryIds為第二步生成的queryId數組:
int startRow = (page - 1) * pageSize
int endRow = page * pageSize - 1;
if (endRow >=queryIds.length)
{
endRow = this.queryIds.length - 1;
}
long startId =queryIds[startRow];
long endId =queryIds[endRow];

查詢語句如下:
String sql = "select * from test_table" + 查詢條件 + "(queryId <= " + startId + " and queryId >= " + endId + ")";

3.效果評價
該分頁查詢方法對所有資料庫都適用,對應用伺服器、資料庫伺服器、查詢客戶端的cpu和內存佔用都較低,查詢速度較快,是一個較為理想的分頁查詢實現方案。經過測試,查詢4百萬條數據,可以在3分鍾內顯示出首頁數據,以後每一次翻頁操作基本在2秒以內。內存和cpu佔用無明顯增長。

以上也僅僅是分頁查詢結果查看的問題,你需要寫入到Excel的話還需要考慮Excel寫入代碼的執行效率,這部分是很值得研究的。

G. sql分批查詢

搜第二行的後面兩條數據
SELECT * From im_friend WHERE id > '' ORDER BY 'id' ASC LIMIT 0,2

H. sql2008資料庫,九百萬條數據,如何快速查詢

根據你說的需求:
"可程序中需要查詢每行的所有數據"、「查詢全部九百萬條數據」

-------------------------------
這樣的需求跟索引沒有關系了(因為已經肯定是走全表掃描的了),要提高效率的辦法就是:1、提高硬碟的io速度;2、增加內存以使sql server有更多的緩存

另外,你程序不要一次性取那麼多數據返回,這樣會拖死的,建議你考慮變換下處理邏輯(如:分批取回--可以根據id列值進行分批;將數據直接在服務端存成文本再傳回本地處理)。

"而是需要根據這些數據逐一進行其他功能的操作,這款程序是不聯網的"
--------------------------------
就算這樣的話,也不能一次性把9百萬數據一次性取回,如果你非要取出來再操作的話,那你得考慮分批去取。或者你把處理邏輯寫在存儲過程,然後由SQL SERVER本身去完成邏輯處理。總之,不管怎樣,你也是得優化你現在的處理邏輯(現有處理邏輯我覺得不合理,效率很低下)。

「真正部署到電力網的伺服器上速度會不會提高呢」
------------------------
伺服器當然比你本地要快得多啦,硬體配置根本就不同一個級別,但不管怎樣,還是建議你參考上面的建議優化你的處理邏輯才行,否則,你系統的效率將很低。