【发布时间】:2017-01-29 13:47:54
【问题描述】:
所以我有两张桌子:
1
CREATE TABLE `adstable` (
`adid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`adbudget` decimal(14,7) unsigned NOT NULL DEFAULT '0.0000000',
`targetdesktop` tinyint(1) NOT NULL DEFAULT '1',
`adactive` tinyint(1) NOT NULL,
`user` bigint(20) unsigned NOT NULL,
`approved` tinyint(1) NOT NULL,
`imp_today` int(10) unsigned NOT NULL DEFAULT '0',
`targetwindows` tinyint(1) NOT NULL,
PRIMARY KEY (`adid`),
KEY `user_index` (`user`),
KEY `budget_index` (`adbudget`) USING BTREE,
KEY `imp_today_index` (`imp_today`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=719102 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
2
CREATE TABLE `userstable` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`balance` decimal(14,7) unsigned NOT NULL DEFAULT '0.0000000',
PRIMARY KEY (`id`),
KEY `balance_index` (`balance`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
我有两个 MySQL 查询:
1
SELECT adstable.adid FROM adstable INNER JOIN userstable ON (adstable.user = userstable.id )
WHERE
adstable.adactive=1 AND adstable.approved = 1 AND
adstable.targetdesktop = 1 AND adstable.targetwindows = 1 and
adstable.adbudget > 0.02 AND userstable.balance > 0.02
ORDER BY adstable.imp_today ASC limit 1
2
SELECT adstable.adid FROM adstable INNER JOIN userstable ON (adstable.user = userstable.id )
WHERE
adstable.adactive=1 AND adstable.approved = 1 AND
adstable.adbudget > 0.02 AND userstable.balance > 0.02
ORDER BY adstable.imp_today ASC limit 1
第一个查询在 where 子句中有一个额外的条件:adstable.targetdesktop = 1 AND adstable.targetwindows = 1
但我无法理解的是为什么第一个查询需要 2-3 秒才能运行,而第二个查询需要 2-3 秒。
注意事项:
- adstable 有大约 70 万行
- 第二个和第一个查询都返回相同的 2 行(但额外的 第一个查询中的条件使它慢得多)
- 我通过删除 adstable.adactive=1 AND adstable.approved 运行了查询 1 = 1 而不是 adstable.targetdesktop = 1 AND adstable.targetwindows = 1,查询运行时间为 0.001 秒。
有谁知道为什么第二个查询比第一个快得多,即使第二个返回的行数和第一个相同?
【问题讨论】:
-
我的逻辑是:你使用的条件越多 -> 引擎需要做的比较越多 -> 需要更多的时间。确保主动和批准字段的字段类型是“合法的”(据我了解,它们应该是布尔值 - 例如不是 INT 或 VARCHAR)。
-
@OfirBaruch 我认为 tinyint(1) 和 boolean 是等价的?
-
是的。您是否在 phpmyadmin 中测试查询?
-
@OfirBaruch 第一个查询与第二个查询相同,但有两个额外的比较。但是,如果没有这两个比较,第一个查询仍然会返回相同的行......所以我不明白开销(2 秒的差异)。是的 phpmyadmin
-
即使返回相同的行 - 引擎仍然需要运行所有条件。很遗憾,我没有其他答案。
标签: php mysql indexing query-optimization