1

我有一张看起来像这样的大桌子:

CREATE TABLE `images` (
  `image_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `data` mediumblob,
  PRIMARY KEY (`user_id`,`image_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

我必须在其上运行一个压缩 blob 字段的查询。MySQL 是否能够通过以下查询使用索引:

UPDATE images SET data = COMPRESS(data) WHERE (user_id = ? AND image_id = ?) OR (user_id = ? AND image_id = ?) OR (...) OR (...);

我必须这样做,因为我无法在单个查询中更新整个表,而且我不能只使用user_id.

编辑:explain并且update不起作用,你们知道,对吧?

4

5 回答 5

2

是的,您的更新将使用表上的索引,因为在 之后引用的唯一列WHERE是您的主键所代表的列。

如果您不确定查询将使用什么,请随意使用以下EXPLAIN命令: http ://dev.mysql.com/doc/refman/5.0/en/explain.html

于 2012-05-28T20:17:07.507 回答
2

利用

EXPLAIN SELECT data FROM images
  WHERE (user_id = ? AND image_id = ?)
    OR (user_id = ? AND image_id = ?)
    OR (...)
    OR (...);
于 2012-05-28T20:34:41.233 回答
1

是的,它很可能会使用索引(除非您的条件具有非常低的基数)。

MySQL也支持这种语法:

(user_id, image_id) IN ((user1, image1), (user2, image2), (user3, image3))

但是这个不会使用索引(这只是一个实现缺陷)。

您还可以使用此查询:

UPDATE  (
        SELECT  user1 AS user_id, image1 AS image_id
        UNION ALL
        SELECT  user2 AS user_id, image2 AS image_id
        UNION ALL
        SELECT  user3 AS user_id, image3 AS image_id
        ) q
JOIN    images i
ON      (i.user_id, i.image_id) = (q.user_id, q.image_id)
SET     i.data = COMPRESS(i.data)

这也将使用索引。

于 2012-05-28T20:44:11.670 回答
1

在您的示例中,我希望 MySQL 使用主键作为聚集索引。这意味着索引存储所有列,实际上是磁盘上数据的唯一版本。

所以是的,它将使用索引。在包含ors 的条件下,我希望 MySQL 扫描索引(而不是查找。)

于 2012-05-28T20:16:11.010 回答
1

EXPLAIN比猜测太多要好。

甚至在运行之前EXPLAIN,发出ANALYZE TABLE以确保查询优化器有最佳机会找到最佳查询计划。

于 2012-05-28T20:20:06.630 回答