一个数据库的查询速度很慢,但他的拷贝速度很快

lpwwtiir  于 2021-06-20  发布在  Mysql
关注(0)|答案(6)|浏览(352)

我们有一个laravel应用程序(版本5.4.18),它连接到mysql(5.6.38)数据库(总共30万行),myisam类型。我们有api响应,比如 Model::with('anothermodel')->paginate(25) ,在某个时刻,这个查询的执行时间已经达到了18秒,这是一个非常大的值。我创建了一个沙盒,其中包含一个live laravel环境的副本,该环境使用exaclty相同数据库的副本(在同一服务器上),现在这个api响应在2,5秒内执行。如果我们试图将sandboxlaravel连接到livedb,那么api的执行时间又是18秒。请检查图像。

所以如果我们假设问题在直播网站的db表中,但是如果我们尝试用 microtime ,然后它将显示生成此查询并从数据库中获取数据所需的时间仅为0.7秒。
因此,如果我们假设问题出在api路由或laravel代码中,但是如果我只是将它复制到子目录(作为沙盒)中,那么同样的代码执行起来没有任何问题。
有什么想法吗?
还有一些服务器信息:php7.0.29在linux服务器上,内存为32gbram。

soat7uwm

soat7uwm1#

你试过在live db上重建索引吗?
在mysql中,这可以通过 REPAIR <table> QUICK 命令(快速修复-仅表示修复索引-重建索引)。
(请在应用前备份数据库。。。几乎没有机会用这个命令破坏数据库,但是……)
一些补充说明:
mysql大多使用自平衡的b+树作为索引,它们试图尽可能地平坦以提供良好的搜索时间。
但在某些情况下(通常与向datetime列中插入增量数据有关),例如。 createdAt 使用索引)mysql b+树实现无法处理此类负载。生成的树提供的性能在一段时间(天、周)内不断降低。这样的索引必须重建。。。
如果这种方法有助于您的话-每一次重建一次索引 x 天(上一次每周为我工作一次)

8i9zcol2

8i9zcol22#

我有3个解决方案:
1) 使用以下命令检查、优化和修复表:

mysqlcheck -u root -p --auto-repair --check --optimize --all-databases

2) 如果问题没有解决,请使用newrelic等监控应用程序检查查询执行计划
3) 有时不是关于特定的表,而是数据库损坏,尝试删除旧数据并创建一个新的表。如何恢复/重建mysql的默认“mysql”数据库

daolsyd0

daolsyd03#

可能有两个问题,一个是重建索引,在这之前,索引已被处理并进行备份,
另一个是您正在运行的服务器,我指的是apache或nginx。
查看为apache运行的内容

ps auxf

通过打开服务器状态监视apache

apachectl fullstatus

这是一本关于apache性能的好书

2nbm6dog

2nbm6dog4#

你需要修复你的数据库。
为什么要压缩和修复数据库
本概述介绍了使用compact和repair database命令如何帮助防止和纠正以下有时会影响数据库的问题:文件随着使用而变大,文件也会损坏。
数据库文件随着使用的增长而增长当您添加和更新数据并更改其设计时,数据库文件会变得更大。这些增长部分来自新数据,但也有一些来自其他来源:
access创建临时的隐藏对象来完成各种任务。有时,在access不再需要这些临时对象之后,这些临时对象会保留在数据库中。
删除数据库对象时,对象占用的磁盘空间不会自动回收—即使对象已被删除,数据库文件仍会使用该磁盘空间。
当您的数据库文件被临时对象和已删除对象的剩余部分填满时,其性能可能会降低。对象的打开速度可能较慢,查询的运行时间可能比正常情况下长,典型的操作通常需要更长的时间。
参考文献:
https://support.office.com/en-us/article/compact-and-repair-a-database-6ee60f16-aed0-40ac-bf22-85fa9f4005b2

klh5stk1

klh5stk15#

这是我个人的经验与非常大的数据库,数据超过800万条记录。我不知道这有多大帮助,但它在这里。
对于非常大的记录,您尝试执行的查询会极大地影响响应所需的时间。例如,假设您正试图搜索一个名为 "" 想把它翻出来。对于这两个查询将被执行。
第一个查询将统计以name开头的所有记录 `` 但我查了你的数据库。-假设这花了10秒,因为音量很大,它会从上到下移动。
执行第二个查询以获取所需的前10或20条记录。这对时间影响很大。
答。假设你有很多有名字的记录 "" ,因此查询将返回非常少的前10条记录,比如2秒内返回。
b。但是,如果您的记录名为“”的记录很少,那么查询将一直传递到您的数据库,并且还需要10秒,因此现在的总执行时间是20秒,而对于第一种情况,只有12秒。
如果你想知道时间到底花在哪里,你可以用 laravel debugger tool 。这实际上显示了正在执行的查询以及哪个查询花费了多少时间。
几乎没有其他因素,如服务器设置和延迟。你也可以查一下。
对于疑问,我的建议是 simplePaginate() ,直到和,除非要显示总记录。
希望这对你有点帮助。

8tntrjer

8tntrjer6#

没有足够的信息来给出详细的诊断。就我个人而言,当查询执行缓慢时,我会开始检查服务器上的内存和cpu占用情况,htop是一个很好的工具,以防您无法访问任何其他许可软件进行服务器监控,以确保不仅机器是平等的,而且工作负载也是平等的。很多时候,这类问题取决于资源的锁定或争用,而不是特定的查询。最终隔离一个sql序列并在两个服务器上获得解释。此时,您应该能够通过使用同一个客户机(即sqlyog)重现问题,并且能够在重建索引或表之后评估explain和performance上的更改。如果这样做的目的是为了解决问题,并生成关于如何在将来再次修复问题的文档,那么仅仅希望这样做是没有用的。是的,通常由于需要重建的索引而导致的性能下降会在没有仔细的db维护程序的情况下一次又一次地发生。

相关问题