查看: 5399|回复: 9
|
MSSQL query 加速ing
[复制链接]
|
|
题目1:我有3个query:
SELECT A.* FROM TABLE A, TABLE B, TABLE C
WHERE A.ID = B.ID AND B.SUBID = C.SUBID AND A.NAME = XXXX AND C.ADDRESS = YYYY
OR
SELECT A.* FROM TABLE A
INNER JOIN TABLE B ON A.ID = B.ID
INNER JOIN TABLE C ON B.SUBID = C.SUBID
WHERE A.NAME = XXXX AND C.ADDRESS = YYYY
OR
SELECT A.* FROM TABLE A
INNER JOIN TABLE B ON A.ID = B.ID AND A.NAME = XXXX
INNER JOIN TABLE C ON B.SUBID = C.SUBID AND C.ADDRESS = YYYY
--
那个会比较快??
---------------------------------------------
题目2:曾经看过网上有论文说用IN 和 EXISTS。。exists会比较快。。
因为IN会scan完全部value,才会在parent query process, 而EXISTS的道理是Yes or No。。
但是我发生过用IN的statistics IO 比较少。。反而EXISTS 的 statistics IO 还要高。。
有没有人遇到这样的问题? |
|
|
|
|
|
|
|
发表于 14-9-2015 03:04 PM
|
显示全部楼层
觉得应该是第二个比较快。。
如果你有加index和primary key。 |
|
|
|
|
|
|
|
发表于 14-9-2015 11:19 PM
|
显示全部楼层
本帖最后由 gkheng2003 于 14-9-2015 11:21 PM 编辑
我怀疑sql query plan 应该一样快 after optimizaton (at least 1st & 2nd i tried similar not same on MSSQL)
- SELECT e.* FROM [HumanResources].[Employee] e, [Person].[Contact] c , [HumanResources].[EmployeeAddress] ea
- where c.[ContactID] = e.[ContactID] and e.[EmployeeID] = ea.[EmployeeID] and LoginID = 'adventure-works\guy1'
- -------------------------------------------------
- SELECT e.* FROM [HumanResources].[Employee] e
- INNER JOIN [Person].[Contact] c
- ON c.[ContactID] = e.[ContactID]
- INNER JOIN [HumanResources].[EmployeeAddress] ea
- ON e.[EmployeeID] = ea.[EmployeeID]
- where LoginID = 'adventure-works\guy1'
复制代码
ur exetion plan? maybe can try "client statistics funcation"?
|
|
|
|
|
|
|
|
楼主 |
发表于 15-9-2015 08:12 PM
|
显示全部楼层
本帖最后由 阿福928 于 15-9-2015 08:13 PM 编辑
我的execution plan 是差不多一样 。。只是我想知道如果以performance 来看,那个比较快。。
我的意思。。如果我们比较注重query的performance。。我们会选择1,2 还是 3?
|
|
|
|
|
|
|
|
发表于 16-9-2015 12:35 AM
|
显示全部楼层
as far as i know; 如果都是同样的 execution plan, it does not matter how u write it. MSSQL pulls at same speed.
unless u care on how much bytes u send to server?
|
|
|
|
|
|
|
|
楼主 |
发表于 16-9-2015 06:41 PM
|
显示全部楼层
我关心的是logical read 和 phycical read 会有影响吗?还是这些reading是另外一回事。。
|
|
|
|
|
|
|
|
发表于 16-9-2015 10:41 PM
|
显示全部楼层
not db expert
不过我怀疑2件事:
1) query execution plan is similar to Common-Runtime; thus C#/VBNET/Boo/j# should run with same speed if same IL code
2) phycical read is more to table design (column size, normalization, ...) . not on SP in this 1st case (2nd case IN & EXIST diff)
|
|
|
|
|
|
|
|
发表于 19-9-2015 07:26 PM
|
显示全部楼层
大家好
我先講下小弟的淺見, 我只有很少的MSSQL的經驗, 所以我說的不一定是準確的
如果資料量很大的話, 就以SQL語法來看, 我認為第三個的Query執行會比較迅速.
為何?
Join 3個table 的complexity 大致上會像下面那樣
PS: M為table A的 row 數量, N為B的數量以此類推.
所以第三個語法會先篩選 table C的數量, 再來Join
以複雜度來看, P如果數量減少了之後, 整體是會快一些.
但是如果以table 設計來看(Normalize 或 data modeling)
A的 Primary Key(ID) = B的 Primary Key(ID), 意思就是:
A 跟 B的關係是一對一, 這表示你把data set 拆成 A跟B根本就是多餘, 如果你不拆table , 你整體上的query 就只要Join兩個, 你就不需要那邊煩惱這個問題了.
別忘記Database Design 的最基礎口訣是:
Reduce Redundancy
Increase Efficiency 把資料分拆成兩個table 是要解決 Redundancy 的問題, 但是一定的程度上會減少Efficency,
既然你的data 不是一對多或多對多, 在設計的時候就不會去考慮分拆成A跟B兩個table.
當然你可以說
A跟B併起來Column 太多, 效率會變差, 拆出來會比較好. 但是如果是那樣, 又牽涉到另外一個設計模式的迷思, 等有機會我在說出來. 這裏我就不多說.
另外一個table C, 也是有明顯設計上的錯誤, 就是
如果B的SubID 跟C 的SubID 同樣屬於Unique的話, 情況就跟上面一樣, 一對一的table是不需要分拆的, 拆了等同脫褲子放屁.
也就是說你只要create 一個 ABC的table就好, 省略join的時間.
如果雙方不是Unique 的話, 這也是個問題, 就會造成 B跟C 的table 會是多對多的關係, 如下所示:
舉凡多對多的關係, 我們在ERD的表達會是這樣的
但是我們實際database migration 的時候會分別創立三個table
B (ID, Field1, Field2)
B_C (ID, B_ID, C_ID)
C(ID, Field1, Field2)
如果你堅持你那種table的設計, 當資料一多, 在join C 跟 B的時候一定就會出現預想以外的重複data, 本來複雜度應該 O(N*P) 但是會變成 O(N^P)
總結, 雖然你只是想問三個 join 的比較(其實答案很簡單), 但是你的前提(問題)在邏輯上是有很多沒有思考的地方, 就算是你裡真理很近, 但是你沒辦法驗證他, 因為你思考的方向本來就是錯的.
這讓我想起一句話:
|
评分
-
查看全部评分
|
|
|
|
|
|
|
发表于 30-10-2015 03:47 AM
|
显示全部楼层
本帖最后由 moot 于 30-10-2015 03:51 AM 编辑
不同的DBMS Explain plan 都不同,内部优化后很可能一样。在Postgresql, mysql ,oracle,mssql 表现会完全不同。
逻辑上来说, 有index , WHERE A.NAME = XXXX 会优先. 没有的话,就会整个table select. WHERE A.NAME LIKE "%XXXX%" 是整个table A , 然后只找AND C.ADDRESS = YYYY
不过内部优化不会跟你这样说的。
DBMS 有时候经过多人的不同设计,会出现哭笑不得的情形。 #8楼的道理未必能符合你的需求, 要看B 对A 是否是1:1 ,是的话, 常用这SELECT , 把B和A merge 是正常的做法。 要不然,就把B SUBID 备份给A。 然后A就可以直接看到C . Reduce Redundancy 的 Normalisation 不是必然的。 Increase Efficiency 才是正道。denormalisation 的例子很多。
当然,这要看为何B 会成为这样的设计。比如说做full table scan report select , Table A 有个Column 很大,拉慢整体的update, 那就不得弄出一个sub table.(用redundancy disk space 抢速度). 不过用处必须被记录下来。可惜很多做程式设计的人, 都不喜欢做记录。 有些猪头会说, 我有放trigger update A 和B, 你看看就知道干什么。
|
评分
-
查看全部评分
|
|
|
|
|
|
| |
本周最热论坛帖子
|