- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
当前的实现是一个具有多个连接和临时表的复杂查询,但对我的 MySQL 造成了太大的压力,并且需要超过 30 秒以上的时间来加载表。数据由 PHP 通过 JavaScript Ajax 调用检索并显示在网页上。这是涉及的表格:
Table: table_companies
Columns: company_id, ...
Table: table_manufacture_line
Columns: line_id, line_name, ...
Table: table_product_stereo
Columns: product_id, line_id, company_id, assembly_datetime, serial_number, ...
Table: table_product_television
Columns: product_id, line_id, company_id, assembly_datetime, serial_number, warranty_expiry, ...
单个公司可以在两个产品表之间拆分超过 10 万个项目。产品表按 line_name 合并和过滤,然后按 assembly_datetime 排序并根据分页进行限制。日期时间值也依赖于时区,这作为查询的一部分应用(另一个 JOIN + 临时表)。 line_name 也是返回的列之一。
我正在考虑将 line_name 过滤器从产品联合查询中分离出来。本质上,我会确定与过滤器对应的行的 ID,然后使用 WHERE 条件执行 UNION 查询 WHERE line_id IN (<results from previous query>)
.这将消除对连接和临时表的需要,我可以在 PHP 中将 line_name 应用于 line_id 和时区修改,但我不确定这是处理事情的最佳方法。
我也考虑过使用 Redis 的可能性,但是当通过 PHP 将所有数据推送到 Redis 时(20-30 秒),大量的单个产品会导致类似的等待时间,即使它只是被拉取直接来自产品表。
感谢您提供的任何意见。
编辑:
现有查询:
SELECT line_name,CONVERT_TZ(datetime,'UTC',timezone) datetime,... FROM (SELECT line_name,datetime,... FROM ((SELECT line_id,assembly_datetime datetime,... FROM table_product_stereos WHERE company_id=# ) UNION (SELECT line_id,assembly_datetime datetime,... FROM table_product_televisions WHERE company_id=# )) AS union_products INNER JOIN table_manufacture_line USING (line_id)) AS products INNER JOIN (SELECT timezone FROM table_companies WHERE company_id=# ) AS tz ORDER BY datetime DESC LIMIT 0,100
为了提高可读性,此处进行了格式化。
SELECT line_name,CONVERT_TZ(datetime,'UTC',tz.timezone) datetime,...
FROM (SELECT line_name,datetime,...
FROM (SELECT line_id,assembly_datetime datetime,...
FROM table_product_stereos WHERE company_id=#
UNION
SELECT line_id,assembly_datetime datetime,...
FROM table_product_televisions
WHERE company_id=#
) AS union_products
INNER JOIN table_manufacture_line USING (line_id)
) AS products
INNER JOIN (SELECT timezone
FROM table_companies
WHERE company_id=#
) AS tz
ORDER BY datetime DESC LIMIT 0,100
ID 已编入索引;主键是每列的第一个键。
最佳答案
让我们从它的组成部分构建这个查询,看看我们可以优化什么。
观察:您正在从两个大型产品表的联合中获取最近的 100 行。
那么,让我们从尝试优化从产品表中获取内容的子查询开始。这是其中之一。
SELECT line_id,assembly_datetime datetime,...
FROM table_product_stereos
WHERE company_id=#
但是看,您只需要这里的 100 个最新条目。所以,让我们添加
ORDER BY assembly_datetime DESC
LIMIT 100
这个查询。此外,您应该在该表上放置一个复合索引,如下所示。这将允许索引满足 WHERE 和 ORDER BY 查找。
CREATE INDEX id_date ON table_product_stereos (company_id, assembly_datetime)
所有相同的注意事项都适用于 table_product_televisions
的查询。按时间排序,限制在100个以内,索引。
如果您需要应用其他选择标准,您可以将它们放在这些内部查询中。例如,在评论中您提到了基于子字符串搜索的选择。您可以按如下方式执行此操作
SELECT t.line_id,t.assembly_datetime datetime,...
FROM table_product_stereos AS t
JOIN table_manufacture_line AS m ON m.line_id = t.line_id
AND m.line_name LIKE '%test'
WHERE company_id=#
ORDER BY assembly_datetime DESC
LIMIT 100
接下来,您将使用 UNION
将这两个查询结果集合并为一个。 UNION
有去重功能,比较耗时。 (您知道您没有重复项,但 MySQL 没有。)请改用 UNION ALL
。
把这些放在一起,最里面的子查询就变成了这个。我们必须结束子查询,因为 SQL 会被同一查询级别的 UNION
和 ORDER BY
子句混淆。
SELECT * FROM (
SELECT line_id,assembly_datetime datetime,...
FROM table_product_stereos
WHERE company_id=#
ORDER BY assembly_datetime DESC
LIMIT 100
) AS st
UNION ALL
SELECT * FROM (
SELECT line_id,assembly_datetime datetime,...
FROM table_product_televisions
WHERE company_id=#
ORDER BY assembly_datetime DESC
LIMIT 100
) AS tv
这会得到 200 行。它应该很快得到这些行。
保证 200 行足以在您执行外部 ORDER BY ... LIMIT
操作后为您提供 100 个最近的项目。但该操作只需要处理 200 行,而不是 100K+,所以它会快得多。
最后将此查询包含在您的外部查询 Material 中。加入table_manufacture_line
信息,并修正时区。
如果您更早地进行索引和 ORDER BY ... LIMIT
操作,这个查询应该会变得非常快。
您问题中的评论对话框向我表明您可能有多种产品类型,而不仅仅是两种,并且您的分页显示有复杂的选择标准。对大量行使用 UNION ALL
会严重影响性能:它将多个索引表转换为一个内部行列表,根本无法有效地进行搜索。
您真的应该考虑将两种产品数据放在一个表中,而不必 UNION ALL
多个产品表。您现在拥有的设置不灵活,不会轻易扩展。如果您使用主产品表和一些产品特定信息的属性表来构建您的模式,那么两年后您会发现自己会更快乐。严重地。请考虑进行更改。
关于php - 在不严重影响数据库的情况下在分页表中显示大量数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26169567/
我有一台 MySQL 服务器和一台 PostgreSQL 服务器。 需要从多个表中复制或重新插入一组数据 MySQL 流式传输/同步到 PostgreSQL 表。 这种复制可以基于时间(Sync)或事
如果两个表的 id 彼此相等,我尝试从一个表中获取数据。这是我使用的代码: SELECT id_to , email_to , name_to , status_to
我有一个 Excel 工作表。顶行对应于列名称,而连续的行每行代表一个条目。 如何将此 Excel 工作表转换为 SQL 表? 我使用的是 SQL Server 2005。 最佳答案 这取决于您使用哪
我想合并两个 Django 模型并创建一个模型。让我们假设我有第一个表表 A,其中包含一些列和数据。 Table A -------------- col1 col2 col3 col
我有两个表:table1,table2,如下所示 table1: id name 1 tamil 2 english 3 maths 4 science table2: p
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 1 年前。 Improve th
下面两个语句有什么区别? newTable = orginalTable 或 newTable.data(originalTable) 我怀疑 .data() 方法具有性能优势,因为它在标准 AX 中
我有一个表,我没有在其中显式定义主键,它并不是真正需要的功能......但是一位同事建议我添加一个列作为唯一主键以随着数据库的增长提高性能...... 谁能解释一下这是如何提高性能的? 没有使用索引(
如何将表“产品”中的产品记录与其不同表“图像”中的图像相关联? 我正在对产品 ID 使用自动增量。 我觉得不可能进行关联,因为产品 ID 是自动递增的,因此在插入期间不可用! 如何插入新产品,获取产品
我有一个 sql 表,其中包含关键字和出现次数,如下所示(尽管出现次数并不重要): ____________ dog | 3 | ____________ rat | 7 | ____
是否可以使用目标表中的LAST_INSERT_ID更新源表? INSERT INTO `target` SELECT `a`, `b` FROM `source` 目标表有一个自动增量键id,我想将其
我正在重建一个搜索查询,因为它在“我看到的”中变得多余,我想知道什么 (albums_artists, artists) ( ) does in join? is it for boosting pe
以下是我使用 mysqldump 备份数据库的开关: /usr/bin/mysqldump -u **** --password=**** --single-transaction --databas
我试图获取 MySQL 表中的所有行并将它们放入 HTML 表中: Exam ID Status Assigned Examiner
如何查询名为 photos 的表中的所有记录,并知道当前用户使用单个查询将哪些结果照片添加为书签? 这是我的表格: -- -- Table structure for table `photos` -
我的网站都在 InnoDB 表上运行,目前为止运行良好。现在我想知道在我的网站上实时发生了什么,所以我将每个页面浏览量(页面、引荐来源网址、IP、主机名等)存储在 InnoDB 表中。每秒大约有 10
我在想我会为 mysql 准备两个表。一个用于存储登录信息,另一个用于存储送货地址。这是传统方式还是所有内容都存储在一张表中? 对于两个表...有没有办法自动将表 A 的列复制到表 B,以便我可以引用
我不是程序员,我从这个表格中阅读了很多关于如何解决我的问题的内容,但我的搜索效果不好 我有两张 table 表 1:成员 id*| name | surname -------------------
我知道如何在 ASP.NET 中显示真实表,例如 public ActionResult Index() { var s = db.StaffInfoDBSet.ToList(); r
我正在尝试运行以下查询: "insert into visits set source = 'http://google.com' and country = 'en' and ref = '1234
我是一名优秀的程序员,十分优秀!