1

这是我的情况:

我正在构建一个产品目录系统,该系统具有许多搜索条件,用户可以通过直接请求或用户的权限、位置或其他元数据添加这些条件。

  1. 有一个主查询正在完成繁重的工作,它相当大并且包含可变数量的子查询以使魔术发生。该查询返回 9 列,其中没有包含太多数据,其中一些通常只是空的。

  2. 我需要在其后的其他几个查询中访问此查询的结果数据(例如,对结果数据进行排序、应用第二层过滤器、分页、选择备用过滤器选项)。

  3. 在 PHP 端,我只需要 25 项的分页结果,所以我想将我的数据库数据保存在数据库中。

我正在使用的解决方案是创建一个临时表,并将数据插入/选择其中。

CREATE TEMPORARY TABLE `tmp_table`
(
    `col1` bigint(20) NOT NULL,
    `col2` int(11) NOT NULL,
    `col3` varchar(16) NOT NULL,
    `col4` decimal(10,2) NULL,
    `col5` decimal(10,2) NULL,
    `col6` decimal(10,2) NULL,
    `col7` decimal(10,2) NULL,
    `col8` decimal(10,2) NULL,
    `col9` tinyint(1) NULL,
    `col10` int(11) NULL,
    `col11` int(11) NULL
) ENGINE=MEMORY;

INSERT INTO `tmp_table` (col1, col2, etc.)
SELECT [...large query]

问题:大型查询本身在 <0.3s 内执行,但是添加临时表插入会在 3.5s ~ 5.0s 之间推动执行

我尝试过 MEMORY、InnoDB 和 MyISAM 作为表引擎,结果都相似。

我已经尝试过在临时表上使用和不使用索引,这似乎对执行时间也没有太大影响。

对于 50 或 500 个结果集,执行时间几乎相同。

我的问题:这种方法不合适吗?是否有任何 MySQL 配置变量我应该查看以提高性能?有没有我忽略的更好的解决方案?

4

1 回答 1

0

您可以将会话 ID 的另一列添加到您的表中,并使其成为非临时的。然后,第一个查询只会将其数据插入到该表中,并且您会不时清理它以删除过期会话的数据。这避免了为每个请求创建表的开销。

很可能,您也会在插入之前删除所有会话特定数据。

于 2013-08-20T18:07:37.703 回答