日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

如何應(yīng)付表數(shù)據(jù)過大的查詢問題?(如何盡量避免大

系統(tǒng) 1895 0
原文: 如何應(yīng)付表數(shù)據(jù)過大的查詢問題?(如何盡量避免大表關(guān)聯(lián))

???? 一般來說,對于做B/S架構(gòu)的朋友來說,更有機(jī)會遇到高并發(fā)的數(shù)據(jù)庫訪問情況,因?yàn)楝F(xiàn)在WEB的普及速度就像火箭升空,同時(shí)就會因?yàn)楦咴L問量帶來一系列性能問題,而數(shù)據(jù)庫一直是用戶與商人之間交流的重要平臺.用戶是沒有耐心忍受一個(gè)查詢需要用上10秒以上的,或者更少些,如果經(jīng)常出現(xiàn)服務(wù)器死機(jī)或者是報(bào)查詢超時(shí),我想那將是失敗的項(xiàng)目。做了幾年的WEB工作,不才,一直沒有遇到過大訪問量或者是海量數(shù)據(jù)的情況.這里并不是說沒有海量數(shù)據(jù)的項(xiàng)目就不是好項(xiàng)目,要看項(xiàng)目的應(yīng)用場合.
?

???? 最近做項(xiàng)目時(shí),偶然得到了這個(gè)機(jī)會,在我工作過程中,本人發(fā)現(xiàn)的單表最大記錄數(shù)高達(dá)9位數(shù).像訂單表什么的也有8位數(shù).在查詢訂單的時(shí)候往往不能通過單表查詢就能解決,還要和其它相關(guān)表進(jìn)行關(guān)聯(lián)查詢.如此關(guān)聯(lián)的表數(shù)據(jù)不大還好,一旦發(fā)生大表關(guān)聯(lián)大表,在查詢時(shí)就有可能出現(xiàn)慢長的等待。
?

??? 主旨: 如何避免這種情況的發(fā)生呢?既然有了這樣的數(shù)據(jù),需求還是要實(shí)現(xiàn),這里就我最近針對數(shù)據(jù)庫的優(yōu)化過程,我分兩篇文章來說明下.
??? 第一篇:如何盡量避免大表關(guān)聯(lián).
??? 第二篇:對大表進(jìn)行分區(qū).

??? 背景: 有兩張表:
?????? 1:訂單表:記錄用戶訂單的詳細(xì)信息. order ,其中有一個(gè)會員卡號字段 cardNo ,訂單產(chǎn)生時(shí)間.
?????? 2:會員表:記錄會員相關(guān)信息. member ,一個(gè)會員有一個(gè)代理號: proxyID ,代理下面有許多的會員卡: cardNo ,它們共用一個(gè)代理號.

?????? 兩表通過cardNo來相關(guān)聯(lián).
?

??? 需求: 查詢一個(gè)用戶或者某些用戶某一時(shí)間段所有會員卡產(chǎn)生的訂單情況.
?

? ? 實(shí)現(xiàn)SQL:

??????? select 字段 from order

??????????? inner join member on
????????????? order.cardNo=member.cardNo
??????????????? and member.proxyID in('a-01',代理號二)

???????????????? and 時(shí)間 between '20080101' and '20080131'
?

?? 本人見解: 我想一般的朋友看到這樣的需求大多會寫出這樣的查詢SQL,如果不喜歡用 in 或者認(rèn)為in的性能不好的朋友可用 union all 代替.SQL語句可以說簡單的不能再簡單了,本身并無問題,只是如果兩表的數(shù)據(jù)都在百萬以上,而且字段都特別多.此時(shí)如果只有索引的幫忙下并不一定能達(dá)到預(yù)期的效果.

??

??? 解決方案一: 利用 表變量 來替換大表關(guān)聯(lián),表變量的作用域?yàn)橐粋€(gè)批處理,批處理完了,表變量也會隨之失效,比起臨時(shí)表有它獨(dú)特的優(yōu)點(diǎn):不用手動去刪除表變量以釋放內(nèi)存。

?? 可行性: 因?yàn)樾枨笾械妮敵鲎侄未蠖鄟碜杂唵伪?member表只起到數(shù)據(jù)約束的作用,和查詢用戶會員卡號的作用,所有可以先把代理的會員卡號先取到表變量中,然后利用帶有卡號的表變量和訂單表相關(guān)聯(lián)查詢.
?? declare @t table
?? (cardNo int)
?? insert @t
???? select cardNo from member where in('a-01',代理號二)
?? select 字段 from order
??????????? inner join @t on
????????????? order.cardNo=@t.cardNo and 時(shí)間 between '20080101' and '20080131'

??? 這里我就不貼性能比較圖了,有興趣的朋友可以自己嘗試下.這種方法在查詢?nèi)藛T比較多的時(shí)候特別有幫助.它要開發(fā)員根據(jù)實(shí)際情況詳細(xì)比較,結(jié)果并不是統(tǒng)一的,不同的環(huán)境結(jié)果可能不一樣.希望大家理解.

?

?? 解決方案二: 利用索引視圖來提高大表關(guān)聯(lián)的性能.
?

?? 可行性: 一般在大表關(guān)聯(lián)時(shí),我們的輸出列都遠(yuǎn)小于兩表的字段合,像上面的member表只用到了其中的兩個(gè)字段(cardNo,proxyID).設(shè)想一下,此時(shí)的member表如果只有這兩個(gè)字段情況會不會好些呢?答案不言而喻.
?

?? 視圖這個(gè)名詞在我以前對它的印象中,從來沒有認(rèn)為視圖能優(yōu)化查詢,因?yàn)槲艺J(rèn)為視圖對于數(shù)據(jù)庫來說就是一個(gè)虛假表,在數(shù)據(jù)庫中并無實(shí)際物理位置來存儲數(shù)據(jù).對于用戶來說無非就是通過不同的視角來觀看結(jié)果.視圖數(shù)據(jù)

的產(chǎn)生都是實(shí)時(shí)的,即當(dāng)調(diào)用視圖時(shí),自動擴(kuò)展視圖,去運(yùn)行里面相應(yīng)的select語句.后來才知道在2000后的版本中視圖分一般視圖和索引視圖,一般視圖就是沒有創(chuàng)建索引的我印象中的視圖.而創(chuàng)建了視圖后就稱為索引視圖.索引視圖是物理存在的,可在視圖上首先創(chuàng)建一個(gè)唯一的聚集索引,其它字段上也可創(chuàng)建非聚集索引.在不改變基礎(chǔ)表的情況下,起到了優(yōu)化的效果.

?

?? CREATE VIEW memberView
WITH SCHEMABINDING
AS
??? SELECT cardNo,proxyID from member
GO
--以會員卡號創(chuàng)建一個(gè)唯一聚集索引
CREATE UNIQUE CLUSTERED INDEX ix_member_cardNo
??? ON member (cardNo);

GO

? ?? 注意:創(chuàng)建索引視圖要點(diǎn):

? ? ? ? ? ? 1: CREATE VIEW memberView后面要跟上WITH SCHEMABINDING

? ? ? ? ? ? ? ? ? 理由:? 使用 schemaname.objectname 明確識別視圖所引用的所有對象,而不管是哪個(gè)用戶訪問該視圖。
?

?????????????????????????? ? 不會以導(dǎo)致視圖定義非法或強(qiáng)制 SQL Server 在該視圖上重新創(chuàng)建索引的方式,更改視圖定義中所引用的對象。

?

??????????? 2:視圖上的第一個(gè)索引必須為 CLUSTERED 和 UNIQUE。
????????????????? 理由:必須為 UNIQUE 以便在維護(hù)索引視圖期間,輕松地按鍵值查找視圖中的記錄,并阻止創(chuàng)建帶有重復(fù)項(xiàng)目的視圖(要求維護(hù)特殊的邏輯)。必須為 CLUSTERED,因?yàn)橹挥芯奂饕拍茉趶?qiáng)制唯一性的同時(shí)存儲行。

??????????? 3:以下情況可考慮創(chuàng)建索引視圖:

? ? ? ? ? ? ?? ? 可預(yù)先計(jì)算聚合并將其保存在索引中,從而在查詢執(zhí)行時(shí),最小化高成本的計(jì)算。
?
?????????????? ? 可預(yù)先聯(lián)接各個(gè)表并保存最終獲得的數(shù)據(jù)集。
?

?????????????? ? 可保存聯(lián)接或聚合的組合。

? ? ? ? ? ?? 4:基礎(chǔ)表的更新會引發(fā)索引視力的更新。

???????????? 5:索引視圖的創(chuàng)建同時(shí)會帶來維護(hù)上的開銷。

????????????????? 理由:1:因?yàn)樗饕晥D是物理存在的。

? ? ? ? ? ? ? ? ? ? ? ? ?? 2:要額外的維護(hù)索引.

?????????????

???? 實(shí)現(xiàn):SQL:select 字段 from order
??????????? inner join memberView on
????????????? order.cardNo=member.cardNo
??????????????? and member.proxyID=in('a-01',代理號二)

???????????????? and 時(shí)間 between '20080101' and '20080131'

?

? ? ? 總結(jié): 兩種解決方案來看,各有所長,一般可以優(yōu)先考慮使用索引視圖來優(yōu)化大表關(guān)聯(lián)。以上是本人對于如何盡量避免發(fā)生大表關(guān)聯(lián)所采取的措施,望大家指教。

?

注:

?? 本文參考:http://www.51cto.com/html/2005/1115/11396.htm

?????

如何應(yīng)付表數(shù)據(jù)過大的查詢問題?(如何盡量避免大表關(guān)聯(lián))


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 翁牛特旗| 尉氏县| 浦城县| 太原市| 石阡县| 防城港市| 陈巴尔虎旗| 阳曲县| 南通市| 电白县| 卢湾区| 武功县| 六安市| 涟水县| 黄平县| 得荣县| 和平区| 茌平县| 西华县| 左云县| 台东县| 湾仔区| 万全县| 克山县| 连城县| 阿城市| 隆德县| 盐城市| 苗栗市| 安龙县| 肇庆市| 教育| 修水县| 兴安盟| 民和| 通江县| 牟定县| 金山区| 阆中市| 麻城市| 金华市|