(select ctime,..... from `ni000_kline` where ctime>=1514466000 and ctime<1545980340)
UNION all
(select ctime,.....from `SR000_kline` where ctime>=1514466000 and ctime<1545980340)
order by ctime asc
需求是這樣的,有兩個表資料結構一直,存放的是期貨不同品種的k線資料,現在需要把2018年內量表的資料都取出來寫入檔案,大家看看
uj5u.com熱心網友回復:
ctime 是索引uj5u.com熱心網友回復:
兩個表的資料綜合110w左右,查詢的資料結果是19w樣子uj5u.com熱心網友回復:
select * from tt where id in(
(select id (這是主鍵) from `ni000_kline` where ctime>=1514466000 and ctime<1545980340)
UNION all
(select id (這是主鍵) from `SR000_kline` where ctime>=1514466000 and ctime<1545980340)
)
查詢大結果集是如何回傳的:
innodb的資料是保存在主鍵索引上的,所以全表掃描實際是直接掃描表的主鍵索引。所以全掃描時查到的每一行都可以直接放到結果集里面, 然后回傳客戶端。
實際上,服務端并不需要保存一個完整的結果集。取資料和發資料的流程是這樣的:
1、取一行,寫到net_bufffer中,這塊記憶體的大小是由參net_buffer_length定義的,默認16k。
2、重復獲取行,直到net_buffer寫滿,呼叫網路介面發出去。
3、如果發送成功,就清空net_buffer,然后繼續取下一行,并寫入net_buffer。
4、如果發送函式回傳eagain或wsaewouldblock,就表示本地網路堆疊(socket send buffer)寫滿了,進行等待。直到網路堆疊重新可寫,再繼續發送。
從流程中可以看到
1、在一個查詢發送程序中,占用的mysql內部的記憶體最大就是net_buffer_length這么大,并不會達到20G(需要的資料大小)
2、socket send buffer也不可能達到20G(默認定義/proc/sys/net/core/wmem_default),如果socket send buffer 寫滿,就會暫停讀資料的流程。
也就是說mysql是邊讀邊發的。意味著,如果客戶端接收的很慢會導致mysql服務端由于結果發不出去,這個事務的執行時間變長。
如果要減少處于sending to client這種狀態的話,將net_buffer_length引數設定為一個更大的值是一個可選的方案。
查詢陳述句的狀態變化是這樣的(略去無關狀態):
1、mysql查詢陳述句進行執行階段后,首先把狀態設定成sending data;
2、然后發送執行結果的列相關資訊(meta data)給客戶端
3、再繼續執行陳述句的流程
4、執行完成后,把狀態設定成空字串。
也就是說 sending data并不一定是指正在發送資料,而可能是處于執行器程序中的任意階段。
僅當一個執行緒片于等待客戶端接收結果的狀態,才會顯示sending to client,而如果顯示sending data意思只是正在執行。
innodb_buffer_pool_size一般建議設定為可用物理記憶體的60%或80%。
inndob記憶體管理用的是最近最少使用演算法(Least Recently Used,LRU)演算法,這個演算法的核心就是淘汰最久未使用的資料。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/18276.html
標籤:MySQL
上一篇:求大神一句mysql搞定
