2010-09-15 223 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越好。通过这种方式,您不需要查询这些数据,这在每一次页面加载时都不会改变。