当前的实现是具有多个连接和临时表的单个复杂查询,但是给我的 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, ...
一家公司可以在两个产品表之间拆分 100k+ 项。产品表由 line_name 联合和过滤,然后按 assembly_datetime 排序,并根据分页进行限制。datetime 值也依赖于时区,这作为查询的一部分应用(另一个 JOIN + temp 表)。line_name 也是返回的列之一。
我正在考虑将 line_name 过滤器从产品联合查询中分离出来。本质上,我会确定与过滤器相对应的行的 ID,然后使用 WHERE 条件进行 UNION 查询WHERE line_id IN (<results from previous query>)
。这将消除对连接和临时表的需求,我可以将 line_name 应用于 PHP 中的 line_id 和时区修改,但我不确定这是处理事情的最佳方式。
我也研究过可能使用 Redis,但是当通过 PHP(20-30 秒)将所有数据推送到 Redis 时,大量的单个产品会导致同样长的等待时间,即使它只是直接从产品表。
- 是否可以调整现有查询以提高效率?
- 我可以将一些处理推送到 PHP 以减少 SQL 服务器上的负载吗?Redis 呢?
- 有没有办法更好地构建表格?
- 你会建议什么其他解决方案?
感谢您提供的任何意见。
编辑:
现有查询:
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 被索引;主键是每列的第一个键。