我有一个数据库调用,我不确定我是否以最有效的方式执行此操作。基本上,调用使用邮政编码查询事件表,然后加入一个邮政编码数据库,该数据库给出该事件的纬度/经度。然后它将登录用户加入到查询中,并且该用户在登录时有一个lat / lon。因此整个查询从这么多英里的用户lat / lon中提取事件。
我的问题是,是否有更好的方法可以在每次加载页面时调用此查询?存储过程会更快吗?我对他们没有任何经验。我正在使用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 :(得分:0)
是的,这将有助于存储过程。 原因是 1.它使您的数据库层更易于管理 2. SP是预编译的。当您首先运行时,引擎将创建执行计划并保存计划。下次运行时,它将重用该计划。所以你获得了一些性能优势。在你的情况下,如果在制作SP之后带下划线的表没有太多改变(更新/删除),你可能会获得很多好处。如果是,则可以重新启动sp(使用RECOMPILE OPTION运行它),它将创建并保存新计划。
你是怎么做到的。 嗯,这很容易。如果您正在使用HeidiSQL for MySQL Front End或MYSQL enterprise 5.0的查询浏览器,您可能能够以图形方式生成SP。但即使你想从头开始编写它也很容易。
http://dev.mysql.com/doc/refman/5.0/en/stored-routines-syntax.html
从安全的角度来看,也建议使用Sp,因为它们可以阻止SQL注入攻击。拥有SP后,您可以调整表格以使SP更快。 1.在where子句中的列上创建索引(非聚簇) 2.在此索引中包括您在SELECT中引入的列。
在Microsoft SQL Server中,您可以使用覆盖索引。我不确定你是否可以在MYSQL中这样做。但即使你可以尝试创建一个索引,覆盖尽可能多的列,无论是聚簇索引还是非聚簇索引。
HTH
答案 1 :(得分:0)
您希望尽可能多地在Session中存储尽可能多的数据(例如用户的纬度/经度)。这样你就不会在每次加载页面时查询这些数据,而这并没有真正改变。