【问题标题】:Optimizing MySQL queries/database优化 MySQL 查询/数据库
【发布时间】:2010-12-20 05:37:23
【问题描述】:

我有两张表 TABLE A 和 TABLE B。 表 A 包含 100 万 (1,000,000) 条记录和 4 个字段,而表 2 包含 60,000 和 3 个字段。 我正在运行一个查询,它连接这两个表并使用 WHERE 子句查找特定产品,如 WHERE 产品,如 '%Bags%' 和产品,如'Bags%' 等

当我直接在 phpMyAdmin 中运行查询时,它会在大约 1 或 2 秒内返回记录。但是当它们在网站上使用时,根据 MySQL 的“慢查询”日志,它们有时需要 9 或 10 秒。实际上我的网站响应有时很慢,所以经过调查,我发现这是由于 MySQL 造成的,因为我了解到“查询日志缓慢”。

慢查询日志包含执行时间超过 long_query_time 秒且需要检查至少 min_examined_row_limit 行的所有 SQL 语句。

因此,根据该日志,上述查询的“query_time”为 13 秒,而在某些情况下,“query_time”甚至超过 50 秒。

我的两个表都使用主键和索引。所以我想知道如何进一步优化它们,或者有什么方法可以优化 MySQL 设置?

这种网站速度缓慢并非一直发生,但有时(可能一周一次)会持续大约 1 或 2 分钟。它获得了可观的流量,并且还有许多其他查询,我发布的上述只是一个示例。

谢谢

【问题讨论】:

    标签: mysql mysql-management


    【解决方案1】:

    关于 MySQL 和性能相关的所有内容,请查看http://www.mysqlperformanceblog.com/

    使用 EXPLAIN 检查您的查询,有关如何使用 EXPLAIN 作为查询诊断工具的信息,请参阅 herehere

    仅有索引是不够的。您是否正在索引在 WHERE 子句中搜索的字段?您是否还有 WHERE 子句中使用的字段的索引(包括您在 ORDER BY、GROUP BY 和 HAVING 子句中提到的字段以及 JOIN)?如果您在单个索引中对字段进行了分组,那么除非您有一个同时搜索所有这些字段的查询,否则该索引不会被命中。如果您对索引中的字段进行分组,请确保该索引将实际用于您的查询中(EXPLAIN 是您的朋友)。

    也就是说,还有很多其他问题:MySQL 服务器配置不当、服务器调优不当、架构错误。但是您的查询和索引是开始调查的好地方。

    Here 是 MySQL 的 Jay Pipes 对性能最佳实践的一个很好的总结。

    【讨论】:

    • 另外,正如其他人所暗示的那样,您的表现将根据您网站的流量而有所不同。如果您在非高峰时段在 phpMyAdmin 中运行查询,您显然会比您(或访问者)在高峰时段运行查询获得更好的性能。
    【解决方案2】:

    like '%Bags%' 查询无法使用索引进行优化。

    这里提高性能的唯一方法是使用fulltext indexes 或获取sphinx 进行搜索。

    【讨论】:

    • @Ali:那你为什么不用MATCH ... AGAINST搜索呢?
    【解决方案3】:

    这是因为在您要刷新网站页面时会运行一些其他查询。因此,例如,如果您的网站将在页面刷新时运行 8-10 个查询,那么它会比您在 phpmyadmin 中运行单个查询花费更多的时间。如果它需要 1-1.5 分钟来执行,那么它可能不是查询问题,但它也可能与服务器速度有关。

    您也可以使用MATCH() AGAINST() 语句来优化此类搜索查询。

    否则您已经在使用PRIMARY KEY, INDEXES and JOINS,因此无需担心其他事情。

    看看就好。

    谢谢。

    【讨论】:

      【解决方案4】:

      有很多方法可以优化数据库和查询。我的方法如下。

      查看数据库架构,看看是否有意义

      大多数情况下,数据库设计不佳且未规范化。这会极大地影响数据库的速度。作为一般情况,学习 3 范式并始终应用它们。高于第 3 范式的范式通常称为反范式,但这实际上意味着它们打破了一些规则以使数据库更快。

      我的建议是坚持使用第 3 范式,除非您是 DBA(这意味着您知道后续表格并知道自己在做什么)。第 3 次 NF 之后的归一化通常在稍后进行,而不是在设计期间。

      只查询你真正需要的东西

      尽可能过滤

      您的 Where 子句是最重要的优化部分。

      只选择您需要的字段

      从不使用“Select *”——只指定你需要的字段;它会更快,并且会使用更少的带宽。

      小心连接

      就时间而言,加入是昂贵的。确保使用将两个表关联在一起的所有键,并且不要连接到未使用的表 - 始终尝试连接索引字段。连接类型也很重要(INNER、OUTER、...)。

      优化查询和存储过程(最先运行)

      查询速度非常快。通常,您可以在不到一秒的时间内检索到许多记录,即使使用连接、排序和计算也是如此。根据经验,如果您的查询时间超过一秒,您可能可以对其进行优化。

      从最常用的查询以及执行时间最长的查询开始。

      添加、删除或修改索引

      如果您的查询进行全表扫描,索引和适当的过滤可以解决通常非常耗时的过程。所有主键都需要索引,因为它们使连接更快。这也意味着所有表都需要一个主键。您还可以在 Where 子句中经常用于过滤的字段上添加索引。

      您特别想在整数、布尔值和数字上使用索引。另一方面,您可能不想在 Blob、VarChars 和长字符串上使用索引。

      添加索引时要小心,因为它们需要由数据库维护。如果您对该字段进行多次更新,维护索引所花费的时间可能比节省的时间要长。

      在 Internet 世界中,只读表非常普遍。当表为只读时,您可以添加负面影响较小的索引,因为索引不需要维护(或很少需要维护)。

      将查询移至存储过程 (SP)

      存储过程通常比查询更好更快,原因如下:

      Stored Procedures are compiled (SQL Code is not), making them faster than SQL code.
      SPs don't use as much bandwidth because you can do many queries in one SP. SPs also stay on the server until the final results are returned.
      Stored Procedures are run on the server, which is typically faster.
      Calculations in code (VB, Java, C++, ...) are not as fast as SP in most cases.
      It keeps your DB access code separate from your presentation layer, which makes it easier to maintain (3 tiers model).
      

      删除不需要的视图

      视图是一种特殊类型的查询——它们不是表。它们是逻辑的而不是物理的,因此每次运行 select * from MyView 时,都会运行生成视图的查询和视图上的查询。

      如果您总是需要相同的信息,那么视图可能会很好。

      如果你必须过滤视图,这就像在一个查询上运行一个查询——它会更慢。

      调整数据库设置

      您可以通过多种方式调整数据库。更新优化器使用的统计信息、运行优化选项、将数据库设置为只读等...这需要对您使用的数据库有更广泛的了解,并且主要由 DBA 完成。

      ****> 使用查询分析器****

      在许多数据库中,都有一个用于运行和优化查询的工具。 SQL Server 有一个称为查询分析器的工具,它对优化非常有用。您可以编写查询、执行它们,更重要的是,查看执行计划。您可以使用执行来了解 SQL Server 对您的查询所做的工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-18
        • 1970-01-01
        • 1970-01-01
        • 2011-02-27
        • 1970-01-01
        相关资源
        最近更新 更多