php mysql优化

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了php mysql优化脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
我被分配了一些任务,即从一些已保存的数据中为网站创建一些图形统计数据.

事实:
– 有3个数据库在使用中. dbcurrent,dbstats,dbBackup.
dbCurrent是网站的主要数据库
dbStats包含各种统计表和跟踪数据表
dbBackup保存最近五年的统计/跟踪表.

>我将使用的数据来自两个数据库(dbStats,dbBackup)
>表名是:stats2006,stats2007,stats2008等,除了当前的统计数据只是“统计数据”.每个表都有其年份的数据.
>每年数据的表结构是相同的:
PrimaryID字段是整数
PRoductID字段是整数
dateMonITor字段是整数(unixtimestamp)
pageName字段是vArchar(20)
> productID,dateMonitor,pageName字段也有索引

换句话说,在什么日期和哪个页面查看了什么产品.

所以,我认为是从每个表创建一个循环并获取我的数据.
我的每个查询看起来像:

Select COUNT(primaryID) as myCounter From $tablename WHERE $conditions

其中$tablename和$conditions是基于每个循环的变量.
所有条件类似于:

> date1和date2之间的dateMonitor
> pageName =’some val’
> productID IN($comma_separated_values)
>以上的组合

到目前为止,所有这些都正常运作(对于单一产品).

当我尝试创建一个报告来比较’y’年的’x’产品(从admin / moderator动态选择)时,脚本运行时间超过15分钟.

我正在寻找一种方法提高脚本的性能.
到目前为止我使用的逻辑/结构如下:

Loop through products to find the ids to use (typical format is: x,y,z (comma separated values)
OPEn Loop through years/months
Execute one sql query for each affected table/database to get the number of affected rows.
Close year loop
Send data to graph script (jquery jqPlot to be exact) to print on screen

任何帮助/想法赞赏.

编辑:
基于@Narf与UNION ALL的建议,我基于12个子选择语句构建了1个单一查询

每个select语句指的是一个月的持续时间.演示代码


EDIT2:创建组合索引后(如@ypercube所示),我看到执行时间略有减少.

现在我的平均执行时间为11分钟(原始时间为15-17分钟)

这有助于减少执行时间.

谢谢.

SELECT COUNT(*) AS monthlytotal From db1.table1 WHERE dateMonitor>='11676
Loop through products to find the ids to use (typical format is: x,z (comma separated values)
Open Loop through years/months
Execute one sql query for each affected table/database to get the number of affected rows.
Close year loop
Send data to graph script (jquery jqPlot to be exact) to print on screen
Loop through products to find the ids to use (typical format is: x,z (comma separated values) Open Loop through years/months Execute one sql query for each affected table/database to get the number of affected rows. Close year loop Send data to graph script (jquery jqPlot to be exact) to print on screen' AND dateMonitor<='1170284399' AND dateMonitor='test'
UNION ALL
SELECT COUNT(*) AS monthlyTotal FROM db1.table2 WHERE dateMonitor>='1170284401' AND dateMonitor<='1172703599' AND dateMonitor='test' ...
for ($m=1; $m<=12; $m++) { $startDate = mktime(0,1,$m,$myyear); $daysOfMonth = date("t",mktime(10,10,$myYear)); $endDate = mktime(23,59,$daysOfMonth,$myYear); $query_chk1 .= "SELECT COUNT(*) AS monthlyTotal FROM db1.table1 WHERE dateMonitor>='$startDate' AND dateMonitor<='$endDate' AND pageName='test' UNION ALL "; } $query_chk1 = substr($query_chk1,-10);

解决方法

你可以做的并不多,至少因为你已经为所有专栏编制了索引……这是我能想到的最好的:

SELECT COUNT(*)
FROM `stats`
WHERE `productID IN(1,2,3)
    AND `dateMonitor` >= <unixtime from>
    AND `dateMonitor` <= <unixtime to>
    AND `pageName`='<value>'

… 如何:

>正如ypercube评论的那样 – 使用COUNT(*)更快.
>我肯定不知道一点,但我相信使用> =和< =而不是BETWEEN来表示整数应该更快.
您应该尝试的另一件事是一次执行所有查询(如果多于一个).用文字正确解释它会更难,我看到你对sql有很好的把握,所以你应该能够得到逻辑,所以这是一个例子:

假设我们需要搜索2006年5月到2008年4月期间123,13,5和6的ID的产品,以及pageName’test’:

>我们在生成查询之前计算时间戳,并确切地确定我们需要搜索哪些表.

SELECT COUNT(*)AS myCounter
来自stats2006
产品ID IN(5,6,123)
    AND dateMonitor> = 1146430800
    AND pageName =’test’

/ *这里我们只需要检查2006年5月1日00:00:00 * /的时间戳

UNION ALL

SELECT COUNT(*)AS myCounter
来自stats2007
产品ID IN(5,123)
    AND pageName =’test’

/ *这里我们不需要检查dateMonitor字段
   因为全年与我们的时期相符
* /

UNION ALL

SELECT COUNT(*)AS myCounter
来自stats2008
产品ID IN(5,123)
    AND dateMonitor< = 1209589199
    AND pageName =’test’

/ *这里我们只需要查看2008年4月30日23:59:59 * /的时间戳

脚本宝典总结

以上是脚本宝典为你收集整理的php mysql优化全部内容,希望文章能够帮你解决php mysql优化所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。