SQL語句為什麼使用select 會降低查詢速度

時間 2021-05-10 01:08:47

1樓:link

也遇到了這個問題,Select *查詢主鍵很快,但是其他的就很慢了。是不是因為主鍵預設已經建立了索引,還是因為資料型別的問題?

對其他字段新建了索引,問題解決。

2樓:黃贇

這要分析資料頁的儲存。

你翻翻新華字典的最後索引頁就明白了。

你僅翻一頁就可以知道你想查的字,在哪幾頁存在。如果你非要查到儲存這個字的那幾頁上面的所有片語,詞語或者短句,那麼你就要去翻開那幾頁;如果你僅僅想知道,這個字在整本字典中出現了幾頁,那僅看索引頁就行。

select *就是你想知道除了這個字的讀法之外,其他有關這個字的一切。那麼顯然就要費點時間去翻翻。 在資料庫中,就是要去翻頁,去做 table scan 了,而 table scan 的過程中,會讀取一些非必要的資料頁,因為一次磁頭的移動,會帶來 64 pages * 8K 大小的磁碟讀(特指 SQL Server).

而明確的 select FieldName 這種查詢,指名道姓的只要讀取某乙個字段,而恰巧該字段是個索引列,那麼從二叉索引樹搜尋下來,很快就知道要讀取的索引頁範圍了,索引頁的儲存僅儲存了索引值和指標(指向原表的物理位置),查詢命中率特別高也特別有效。此時不用二次根據指標去讀原表資料,自然速度快咯。

3樓:黃自力

寫點補充吧,我覺得樓主想問的不僅僅是select * 與 select 某些(部分)欄位的區別。因為這種區別很明顯啊,樓上的許多人也都解釋了。高讚答案也說明了原因。

還有一部分意思應該問的是 select * 與 select 全字段的區別。那麼,我想說,至今2023年7月,mysql和oracle兩種資料庫,這兩種方式在效率上幾乎沒有區別,區別小到完全可以忽略程度!

4樓:韓飛

sql優化有很重要的一項叫做列裁剪(column pruning)。

如果不考慮索引,sql的執行演算法大概分為sort-base和hash-base,不論是哪種,多出來的列都會帶來很多無用的計算。

5樓:

我是分割線

select c.*,

(select d.number from c_now_data d where d.code=c.

code and d.commodity=c.commodity and d.

export=c.export and d.type=c.

type and d.period=concat(LEFT(c.period,4)-1,RIGHT(c.

period,3))) as tq_number,-- 同期數量

(select d.amount from c_now_data d where d.code=c.

code and d.commodity=c.commodity and d.

export=c.export and d.type=c.

type and d.period=concat(LEFT(c.period,4)-1,RIGHT(c.

period,3))) as tq_amount,-- 同期金額

(select d.total_number from c_now_data d where d.code=c.

code and d.commodity=c.commodity and d.

export=c.export and d.type=c.

type and d.period=concat(LEFT(c.period,4)-1,RIGHT(c.

period,3))) as tq_total_number,-- 同期累計數量

(select d.total_amount from c_now_data d where d.code=c.

code and d.commodity=c.commodity and d.

export=c.export and d.type=c.

type and d.period=concat(LEFT(c.period,4)-1,RIGHT(c.

period,3))) as tq_total_amount -- 同期累計金額

from c_now_data c where c.commodity ='26030000' and c.period ='2015-09'

我是分割線

這個語句的執行速度非常慢,求大神給小弟指點一二,方便的話給個優化方案,在此謝過了。

6樓:

*相比窮舉所有字段,Oracle只是會多乙個查資料字典的開銷(資料庫需要知道*等於什麼),常數級複雜度,oracle的風格一般來說不推薦加schema字首,這樣你才可以通過同義詞動態切換schema.

此外,如果是*就不可能走索引直接訪問的優化了,不過考慮到你的需求是查所有字段,能走該優化的情況很少。

此外,如果程式寫得好,如果增加欄位也不會影響結果。因為欄位有順序,預設新增的是排序在最後。如果你的程式是獲取meta Data的,是可以處理這種變化的情況的。

*和全表掃瞄沒有任何關係,全表還是索引只由where謂語決定。

7樓:hua liu

一般來說,網路開銷是系統延遲裡面最重頭的部分。

什麼記憶體、磁碟、cpu的開銷,不過是微妙級;

網路IO則是毫秒甚至是秒級的。

所以過濾無用欄位的傳輸,比對其他優化帶來的系統響應速度提公升更明顯。

8樓:

你也說了只是解析階段 ,最後執行階段肯定是和select有關。

sql的執行過程是(不考慮查詢快取 )

解析器預處理器 -----》 優化器 -----》 查詢執行引擎 -----》 儲存引擎

1)select * 會讓優化器無法完成上面童鞋的覆蓋索引掃瞄這類優化。

2)網路開銷,如果db和應用程式不在同一臺機器,這種開銷非常明顯3)額外的io,記憶體和cpu的消耗,因為多取了不必要的列。

影響 ,當列比較多,尤其列裡面有長的文字字段,影響越明顯。

解析階段並沒有取資料。

9樓:李拉東

肯定會影響查詢速度。如果select的字段在索引沒內會取索引中的值,而無需對從block內重取。通過查詢計畫看得到這個分別。

10樓:范孝鵬

說一下mysql innodb上的理解。1,不需要的字段會增加資料傳輸的時間,即使mysql伺服器和客戶端是在同一臺機器上,使用的協議還是tcp,通訊也是需要額外的時間。

2,要取的字段、索引的型別,和這兩個也是有關係的。舉個例子,對於user表,有name和phone的聯合索引,select name from user where phone=12345678912 和 select * from user where phone=12345678912,前者要比後者的速度快,因為name可以在索引上直接拿到,不再需要讀取這條記錄了。

3,大字段,例如很長的varchar,blob,text。準確來說,長度超過節的時候,會把超出的資料放到另外乙個地方,因此讀取這條記錄會增加一次io操作。

手機碼字好累啊……

11樓:孫召忠

我個人認為:select * 不會降低查詢速度,但是極端情況下會增加mysql伺服器與web伺服器之間(如果不是同乙個伺服器的話)的資料傳輸的時間。

極端情況指的是:如果字段比較多或者非定長表有text之類的大字段。

以上都是我猜的,我也不知道對不對。

Spark SQL到底支援什麼SQL語句?

RednaxelaFX 當前版本的Spark SQL的SQL parser是在Presto的parser的基礎之上用ANTLRv4寫的,其語法檔案在這裡 sql catalyst parser SqlBase.g4,內容非常清楚了 啊話說Databricks Runtime版Spark中有些有趣的新...

Python中使用for迴圈語句,為什麼輸出的結果不是按順序的?

這是乙個有趣的問題,在 python3.6之前 dict 都是無序的,之後dict都是有序的,但是實際開發過程中,無法保證python版本的情況下,如何確保dict按照我們最初順序呢,這個時候可以通過 OrderedDict 保證我們字典順序保持不變,ps 使用 OrderedDict 需要先 im...

為什麼用SQL而不是Excel VBA?

EXCEL辦公實戰 二者都會一些簡單說幾句 1 SQL叫做結構化查詢語言,聽名字就知道,對資料來源的要求挺高一般用於關係型資料庫查詢.2 Excel VBA VBA雖然是一門指令碼語言,但是好得是語言,其中一般的判斷 迴圈等一應俱全,靈活性要強SQL很多 3 SQL和VBA都有自己的最佳環境,我就是...