mysql查询执行时强制托管端阻塞数据库

时间:2013-04-29 06:28:00

标签: php mysql optimization

我的网站数据库已被托管方阻止... 他们说你的查询花了太多时间来执行......他们发送的消息是:

    This message is to advise you of a temporary block placed on your database. The database "**DATABASE NAME**" was found to be consuming an inordinate amount of processor time, to the point of degrading overall system performance. While we do limit each account to no more than 25% of a system's CPU in our terms of service, we do not actively disable accounts until they greatly exceed that number, which is what happened in this case.

Running Processes:
fastlynx 26884 0.3 0.0 0 0 ? ZN 23:26 0:00 [php] <defunct>

Running Queries:
*************************** 1. row ***************************
USER: USERNAME
DB: SB_NAME
STATE: optimizing
TIME: 40
COMMAND: Query
INFO: SELECT * FROM price WHERE country LIKE '27'/*--*/and/*--*//*!30000if(ascii(substring((user()),11,1))<121,BENCHMARK(151973069.6,MD5(0x41)),0)*//*--*/and/*--*/'x'='x%' GROUP BY country ASC order by country asc limit 0, 12
*************************** 2. row ***************************
USER: USERNAME
DB: DB_NAME
STATE: optimizing
TIME: 54
COMMAND: Query
INFO: SELECT * FROM price WHERE country LIKE '27'/*--*/and/*--*//*!30000if(ascii(substring((user()),4,1))<122,BENCHMARK(151973069.6,MD5(0x41)),0)*//*--*/and/*--*/'x'='x%' GROUP BY country ASC order by country asc limit 0, 12

从上面看,单个表中的查询似乎占用了最多的执行时间...... 我已经通过mysql控制面板优化了数据库中的所有表。 伙计们。帮助我处理这种情况。 提前谢谢....

编辑:

实际查询如下:

SELECT * FROM price WHERE country LIKE 'G%' GROUP BY country ASC limit 0, 12
                               OR
SELECT * FROM price WHERE prefix LIKE '91%' GROUP BY country ASC limit 0, 12

还有一件事......我也有时候像LIka一样使用NOT LIKE:

SELECT * FROM price WHERE country LIKE 'G%' AND country NOT LIKE 'INDIA%' GROUP BY country ASC limit 0, 12

Database Table Price screen shot

1 个答案:

答案 0 :(得分:5)

“优化”是什么意思?如果您已经这样做了,我们就再也无法为您做任何事了。

但是考虑到你使用WHERE country LIKE '27',你并没有那么优化。如果国家/地区始终是整数值,请确保country具有numeric数据类型并且您在其上放置索引。也可以使用WHERE country='27'查询它,因为LIKE语句不使用索引但会执行全表扫描。 (如果您有1000行,每次执行该查询时,所有这1000行都将被加载到内存中并进行检查。)

此外,由于您在国家/地区使用GROUP BYORDER,因此请确保此列上有正确的索引。

但是,由于查询的其他部分是if(ascii(substring((user()),11,1))<121,BENCHMARK(151973069.6,MD5(0x41)),0),您可以忘记快速查询。那条小龙将成为一张大桌子上的小龙。

由于我不知道哪一部分是动态的,哪些是静态的,我无法真正提供优化改进。也许给我们一些关于你想要完成什么的见解,这样我们就可以帮助定义一个更好的数据库结构。

<强>更新

您的查询似乎很奇怪。以最后一个为例。您选择的所有国家/地区均以G开头,然后取消以INDIA开头的国家/地区。上次我检查I不是G,所以第二部分没用,只会增加开销。

SELECT * FROM price WHERE country LIKE 'G%' AND country NOT LIKE 'INDIA%'

现在我不知道你的桌子中有多少个国家,但除非你在另一个星球上添加一些国家,否则不会超过200个。使用200条记录,您几乎可以运行任何查询而不会遇到问题。

我还注意到您在国家/地区使用GROUP BY,这意味着国家/地区会多次出现在列表中。但是,由于您使用SELECT *并且没有任何AGGEGRATE FUNCTIONS,例如SUMCOUNT,我预计每个国家/地区只有一条记录。

考虑到所有因素,这似乎是一个非常糟糕的设计模式,并且不知道你想对数据做什么,我无法帮助你。尽量提供以下

  • 您计划使用SELECT *中的哪个字段,考虑该群组?

  • 前缀是什么?它是一个数字列还是一些代码?使用LIKE '91%'时,您期望得到什么回报?前缀为“91”和“916”的国家/地区?或只是'91'?

  • 表中的国家/地区是否超过一次?

更新2:

截图让事情变得更加清晰。由于您显示的是基于国家/地区(实际上是国家+提供商)的所有信息,因此我会进行以下更改:

  • 从此表中删除前缀列,并为前缀创建一个单独的表,并在此表中添加指向auto_id字段的链接。
  • 在国家/地区列中添加唯一索引(从而删除所有重复项)。如果你不需要前缀,那么你可以选择没有GROUP BY。

  • 如果您经常选择以单个字母开头的所有国家/地区,请将另一列添加为char(1),并在添加/更新行时将该国家/地区的第一个字母添加到该列。在该列上放置一个索引,然后您可以使用SELECT * FROM price WHERE newcol='G'进行选择。如果需要,您仍然可以添加第二部分(不喜欢)。

  • 如果您在国家/地区列上有搜索功能,请查看使用FULL TEXT INDEX