2010-09-15 256 views
0

我有一個數據庫調用,我不知道如果我這樣做是最有效的方式。基本上,這個調用查詢一個帶有郵政編碼的事件表,然後加入一個郵政編碼數據庫,該郵政編碼數據庫給出該事件的歷史記錄zip。然後它將登錄用戶加入到查詢中,並且該用戶在登錄時具有緯度/經度。因此整個查詢從用戶經緯度的許多英里內拉動事件。存儲過程mysql

我的問題,有沒有更好的方式來做到這一點,然後每次頁面加載時調用此查詢?存儲過程會更快嗎?我沒有任何與他們的經驗。我正在使用MySQL。

$this->db->select('*'); 
$this->db->from('events'); 
$this->db->join('zipcodes', 'zipcodes.zipcode = courses.courseZip'); 
$this->db->join('eventTypes', 'eventTypes.eventTypeID = events.eventType'); 
$this->db->where('eventApproved', 1); 
$this->db->select('(DEGREES(ACOS(SIN(RADIANS('.$this->user['userLat'].')) 
    * SIN(RADIANS(latitude)) 
    + COS(RADIANS('.$this->user['userLat'].')) 
    * COS(RADIANS(latitude)) 
    * COS(RADIANS('.$this->user['userLon'].' - longitude))))) * 69.09 AS distance'); 

$this->db->having('distance <', 100); 
+0

從數據庫中選擇'lat' /'long'並開發一個php函數可以做到這一點。 – RobertPitt 2010-09-15 14:15:39

+0

你是什麼意思? lat/lon確實來自事件的數據庫,其中加入了與zipcode表匹配的事件,將事件的郵政編碼匹配到郵政編碼表中的郵政編碼。用戶對象提供自己的經緯度。 – Kyle 2010-09-15 14:17:47

回答

0

是的,這將有助於在這裏有一個存儲過程。 原因是 1.它使你的數據庫層更易於管理 2. SP是預編譯的。當你首先運行它們時,引擎會創建一個執行計劃並保存該計劃。下一次運行時,它將重新使用該計劃。所以你得到一些性能好處。在你的情況下,如果帶有下劃線的表格在創建SP後沒有更改(更新/刪除)太多,你可能會得到很多好處。如果是,那麼你可以重新編譯sp(使用RECOMPILE OPTION運行它),它會創建並保存一個新的計劃。

你是怎麼做到的。 好吧,這很容易。如果您使用HeidiSQL for MySQL前端或MYSQL企業版5.0的查詢瀏覽器,則可能會以圖形方式生成SP。但即使你想從頭開始編碼,也很容易。

http://dev.mysql.com/doc/refman/5.0/en/stored-routines-syntax.html

SP還從安全的角度來看advisible,因爲他們可以阻止SQL注入攻擊。

一旦擁有了SP,您就可以調整表格以使SP更快。 1.在where子句中的列創建一個索引(非集羣) 2.包括您在此索引中引入SELECT的列。

在Microsoft SQL Server中,您可以使用此索引覆蓋索引。我不確定你是否可以在MYSQL中完成。但即使您可以嘗試在聚集索引或非聚集索引中創建一個索引,以覆蓋儘可能多的列。

HTH

+1

謝謝,那很好的建議,我會學習如何做SP。另一方面,我還讓每個事件都保持自己的緯度/經度,所以我現在不需要在查詢中加入郵政編碼數據庫。 – Kyle 2010-09-15 14:34:58

+0

非常好。這將再次獲得一些性能提升 – Ash 2010-09-15 16:41:58

0

你會想保存儘可能多的數據(如用戶的經/緯)在Session越好。通過這種方式,您不需要查詢這些數據,這在每一次頁面加載時都不會改變。