简体   繁体   English

mysql_data_seek的性能影响

[英]Performance implications of mysql_data_seek

I've started to use mysql_data_seek () as an easy way to roll pagination transparently into my database class by shifting the pointer and reading the current 'page'. 我已经开始使用mysql_data_seek()作为通过将指针移动并读取当前“页面”将分页透明地滚动到数据库类中的简便方法。

What are the performance implications of doing this? 这样做对性能有何影响? I am only reading the data I need into PHP itself, but in most cases the SELECT covers the whole table - is this bad, and will I hit problems with massive tables? 我只是将所需的数据读入PHP本身,但是在大多数情况下,SELECT会覆盖整个表-这不好吗,我会遇到海量表的问题吗?

If I understand your idea you select all records in the table, then skip the first n*page records with mysql_data_seek() in order to "get to" the current page and read n records. 如果我理解您的想法,则选择表中的所有记录,然后使用mysql_data_seek()跳过前n *页记录,以“进入”当前页并读取n条记录。 If you have a lot of records you might not want to do that because http://php.net/mysql_data_seek says: 如果您有很多记录,则可能不希望这样做,因为http://php.net/mysql_data_seek表示:

Note: The function mysql_data_seek() can be used in conjunction only with mysql_query(), not with mysql_unbuffered_query() 注意:函数mysql_data_seek()只能与mysql_query()结合使用,不能与mysql_unbuffered_query()结合使用
The difference between mysql_query() and the unbuffered version is that mysql_query() returns only after the whole result set has been copied from the MySQL server to the PHP process' memory while after the unbuffered version each mysql_fetch_xyz() has to receive the next record from the server. mysql_query()和非缓冲版本之间的区别在于,mysql_query()仅在将整个结果集从MySQL服务器复制到PHP进程的内存之后才返回,而在非缓冲版本之后,每个mysql_fetch_xyz()必须接收下一条记录从服务器。 If you have a lot of records and you have to transfer all of them for each single request that sounds a bit suboptimal. 如果您有很多记录,并且对于每个听起来不太理想的单个请求,都必须转移所有记录。
I guess you want to do this to get the total amount of records and the current subset with only one query. 我想您想通过一个查询来获取记录总数当前子集总数。 With MySQL you can have both, a LIMIT clause and the total number of records (that would be in the result set without the LIMIT clause), 使用MySQL,您可以同时拥有LIMIT子句和记录总数(在没有LIMIT子句的结果集中,记录总数),
 SELECT SQL_CALC_FOUND_ROWS id FROM foo ORDER BY id LIMIT 20,10 

see http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows 参见http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows

I imagine that using the appropriate LIMIT clause in your SELECT statement is more efficient (it will definitely save lookup time atleast), but I don't know how the internals of how mysql_data_seek works, specifically if it reads x records and discards them, or whether it works like filesystem seek commands do (sends a signal to MySQL telling it to skip sending the next x records). 我以为在SELECT语句中使用适当的LIMIT子句会更有效(它肯定会至少节省查找时间),但是我不知道mysql_data_seek如何工作的内部原理,特别是如果它读取x记录并丢弃它们,或者是否像文件系统seek命令一样工作(向MySQL发送信号,告诉它跳过发送下一个x记录)。

If it works the first way, I'd expect a minimal speedup doing it this way. 如果它能以第一种方式起作用,我希望这样做的速度会最小。 If it was the later way, I'd expect a speedup, but not as much as simply using the appropriate LIMIT clause. 如果是第二种方法,我希望可以加快速度,但是不如简单地使用适当的LIMIT子句那么LIMIT

The only thing to worry about is table size. 唯一需要担心的是表的大小。

Basically, your tradeoff is between: 基本上,您需要权衡以下因素:

  • Reading the whole table/result into a single resultset, saving round-trips to the database 将整个表/结果读入单个结果集中,从而节省了往返数据库的时间
  • or making multiple bite-sized visits to the DB, one per page 或多次访问数据库,每页一次

If your application means users don't often get past the first page or two, then you're storing big wodges of data unnecessarily. 如果您的应用程序意味着用户不经常访问第一或第二页,那么您就不必要地存储大量数据。 OTOH if your users tend to visit all the pages, and there are many (and each page visit doesn't launch a new page request/resultset, ie you're using dynamic pagination or some semi-persistent server-side memory container), then keeping the resultset in one place is fine, particularly if it's cached between multiple users. OTOH,如果您的用户倾向于访问所有页面,并且访问量很多(并且每次访问都不会启动新的页面请求/结果集,即您正在使用动态分页或某些半永久服务器端存储容器),然后将结果集放在一个位置就可以了,特别是如果结果集在多个用户之间缓存时。

However, unless you've built that into your architecture, you're probably better off using something like 但是,除非您已将其构建到架构中,否则最好使用类似

...LIMIT 10,10

...LIMIT 20,10

etc. in your query though, and suffering the multiple DB hits to avoid having to read more data than you're going to need, and storing it unnecessarily. 等等),并遭受多个数据库命中,以避免不得不读取比您需要更多的数据,并不必要地进行存储。

I ll go with mysql_seek_data() , if the cost of query execution is high. 如果查询执行的成本很高,我将使用mysql_seek_data()。

Normally pagination needs two query executions ref: [ MySQL pagination without double-querying? 通常,分页需要两个查询执行ref:[ MySQL的分页而不进行双重查询? ] ]

a) execute the query to find total no of records returned a)执行查询以查找返回的记录总数

b) execute the query with limit clause to fetch only desired results b)使用limit子句执行查询以仅获取所需结果
For second case please check the question : 对于第二种情况,请检查问题:

If query execution cost is very high, I ll not go for second execution , and opt for mysql_seek_data() function , as I have used it successfully 如果查询执行成本很高,我将不进行第二次执行,而选择mysql_seek_data()函数,因为我已经成功使用了它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM