**訪問日誌都會存在個基本問題,就是根據訪問者ip從ip庫中獲取ip所在國家(貌似有點繞口),它的使用場景比較廣泛,如現在的大部分**都可以通過來訪者的地域推送不同的內容。我們資料倉儲中,則要通過這個來分析**的國家訪問情況。
廢話不多說,上表
session_temp表是我建立的臨時表,從本站某天的真實訪問資料中把使用者的訪問ip全部導過來。本站一天的訪問資料在30000左右
ip_temp表是本站購買的ip庫,主要由三個字段構成
startip、endip指的是該ip段範圍
countryname指的是該ip段所對應的國家
示例值見下圖
比如對於1944892794這個ip,我們獲取它的國家執行如下:
這種查詢單個ip國家的語句一般是使用者訪問的時候做判斷,再根據他的國家做推算。這語句執行了7秒多,意思是使用者來訪問時,要至少7秒時間才能把頁面展示出來,肯定是不能接受的。
我們資料倉儲是對當天全部資料做查詢,則完全無法執行出結果。這樣的速度顯然是不能滿足生產環境的要求的。如下:
8分多鐘還沒出結果,即使資料倉儲中也無法忍受這種速度
**那邊說用mongodb可以解決問題,我還沒試過,估計也不大好整合其他種類資料庫的etl進來。所以還是要從執行計畫入手。先看下這句**的執行計畫
這個執行計畫有點難懂。oracle
先對session_temp做了全表掃瞄排序,因為只有2萬多行,所以應該是記憶體排序,問題不大。然後對根據startip<=ip這個條件,對t2表做了過濾,再全表掃瞄進行排序,400萬條資料排序,估計要用到磁碟了。兩張表排完後開始進行merge連線,連線條件是endip>=ip.
這個執行計畫看著就有點不靠譜,謂語的兩句地位相等,應該都用來做連線條件,結果oracle一句變成了條件過濾語句。endip>=ip這個條件並不是等式連線,如果用merge,意味著從session裡取出一條ip資料,需要在ip庫里把大於這個ip全部掃瞄一遍,效能是o(session+ip_temp*session)+o(sessionlog)+o(ip_templog)(oracle的排序演算法好像是nlogn,記憶體排)(難怪能跑出rows30g的資料), 而merge前的排序本身就是為了減少反覆的全表掃瞄,等於耗了大量精力的排序全部白幹。
既然merge也要兩邊都全表掃瞄,還不如用nest loop,session表遠小於ip庫表,所以它是驅動表。根據這個思路我們加上hints
select /*+leading(t1) use_nl(t1 t2)*/ * from session_temp t1,ip_temp t2 where t2.startip<=t1.ip and t2.endip>=t1.ip
檢視執行計畫
看上去合理了一點,不過各項指標貌似沒有明顯的改善,原因就不知道了。有時候cbo是有點傻,算出來的指標不一定對(暫時這麼解釋吧)。
看看效果:
執行時間還是不能滿足要求。
仔細想想,nest loop會反覆掃瞄外表,如果上面建個索引,每次都index range scan,顯然會快很多。所以在session上建立索引:
執行計畫似乎沒變,還是對兩張表都進行全表掃瞄。
不過後來發現時我理解錯了,谷歌了下hints leading的含義,它表示的是先載入t1表,每次一條資料,再去迴圈掃瞄t2表。那不就意味著t2表是驅動表了?跟我印象中對不上啊(哪本書上說leading引導的是驅動表),不管怎樣,先改改看
貌似這個就是我想要的執行計畫了,先掃瞄t2表,400多萬條資料全表掃一下還是挺快的,去session表關聯,由於是不等式連線,所以是索引範圍掃瞄,索引掃一下也很快。所以這個執行計畫時間複雜度是o(ip_temp+ip_temp*session),session是走索引所以速度非常快,
ip_temp*session時間可忽略不計。
再測試下,這回4秒鐘就出來了
可見執行計畫多麼的重要。
還有些困惑的地方,cbo為啥要搞出這麼個執行計畫(乙個key過濾乙個key連線)?為啥做了隱式轉換?做個10053可能可以搞出來。
oracle資料庫限制IP訪問
通過修改oracle資料庫的ora配置檔案可以實現只有指定ip才能訪問 開啟oracle安裝路徑下 dbhome 1 network admin sqlnet.ora檔案 增加以下 1.tcp.validnode checking yes 開啟ip限制功能 2.tcp.invited nodes 1...
ORACLE 限制特定IP訪問資料庫
1 在9i中真正起作用的是sqlnet.ora檔案,我們修改sqlnet.ora其實是最好最快的方法。在sqlnet.ora中增加如下部分 來自 protocol.ora 的屬性 tcp.validnode checking yes 允許訪問的ip tcp.invited nodes ip1,ip2...
爬取西刺ip的插入資料庫相關問題
今晚解決了前幾天爬取西刺ip網不能插入資料庫的問題,成功爬取並插入資料庫的 如下 encoding utf 8 import re import requests from scrapy.selector import selector import mysqldb conn mysqldb.con...