1

我想调用插入选择并尝试使用此选择(当一列是唯一的时,借助此 INSERT SELECT 查询的帮助)

SELECT minids.userid, username, password, full_name, country, email,
      (select openclipart_files.id from aiki_users, openclipart_files
       where aiki_users.userid = users.userid and avatar like '%svg' AND
             filename = avatar) as avatar,
      homepage, usergroup, notify, nsfwfilter
FROM aiki_users users
INNER JOIN (SELECT MIN(userid) as userid FROM aiki_users GROUP by username) 
           minids ON minids.userid = users.userid;

我用它插入

INSERT INTO openclipart_users(id, user_name, password, full_name, country,
email, avatar, homepage, user_group, notify, nsfw_filter) SELECT ...

执行需要很长时间(我会在几分钟后取消它)

aiki_users 表有 100k 行,openclipart_files 有 30k 行,基本上我只是将所有内容从 aiki_users 复制到 openclipart_users 跳过重复项,我希望头像是旧表中是字符串的文件的 id(只有大约 300 个用户有大约 1k 的 svg 头像用户没有''头像,但我只有什么 svg)。

有什么方法可以快速将该化身(没有它在几秒钟内执行 INSERT SELECT)插入到 openclipart_users 中,任何可行的解决方案都会很好(我的意思是不到一分钟)。

SELECT 上解释的EDIT输出

+----+--------------------+--------------------+--- -----+----------------+----------+---------+------- ---------------+--------+------------- +
| 编号 | 选择类型 | 表| 类型 | 可能的键 | 关键 | key_len | 参考 | 行 | 额外 |
+----+--------------------+--------------------+--- -----+----------------+----------+---------+------- ---------------+--------+------------- +
| 1 | 初级 | <派生3> | 全部 | 空 | 空 | 空 | 空 | 106689 | |
| 1 | 初级 | 用户 | eq_ref | 初级 | 初级 | 4 | minids.userid | 1 | |
| 3 | 派生 | aiki_users | 索引 | 空 | 用户名 | 302 | 空 | 111273 | 使用索引 |
| 2 | 依赖子查询 | openclipart_files | 全部 | 空 | 空 | 空 | 空 | 37715 | |
| 2 | 依赖子查询 | aiki_users | eq_ref | 初级 | 初级 | 4 | openclipart_staging.users.userid | 1 | 使用位置 |
+----+--------------------+--------------------+--- -----+----------------+----------+---------+------- ---------------+--------+------------- +
4

4 回答 4

2

转换为仅连接语法(摆脱相关的子查询并改为连接到子选择):

SELECT minids.userid, username, password, full_name, country, email,
      clip.id as avatar,
      homepage, usergroup, notify, nsfwfilter
FROM aiki_users users
INNER JOIN (SELECT MIN(userid) as userid FROM aiki_users GROUP by username) 
           minids ON minids.userid = users.userid
LEFT OUTER JOIN openclipart_files clip ON 
           clip.owner = users.userid AND RIGHT(users.avatar, 3) = 'svg' 
           AND clip.filename = users.avatar

试试看。

于 2012-07-27T13:46:14.893 回答
1
SELECT 
    MIN(userid), username, password, full_name, country, email,
    openclipart_files.id,
    homepage, usergroup, notify, nsfwfilter
FROM aiki_users 
LEFT JOIN openclipart_files  ON filename = avatar AND avatar like '%svg'
GROUP BY username
于 2012-07-26T17:49:21.167 回答
1

使用@SPFiredrake的提示与 CASE 和 RIGHT 我创建了这个查询

SELECT minids.userid, username, password, full_name, country, email,
       case RIGHT(avatar, 3) 
       when 'svg' then 
            (select openclipart_files.id 
             from openclipart_files
             where filename = users.avatar AND users.userid = owner)
       else 
            null 
       end as avatar, homepage, usergroup, first_login, notify, nsfwfilter
FROM aiki_users users 
INNER JOIN (SELECT MIN(userid) as userid FROM aiki_users GROUP by username) 
minids ON minids.userid = users.userid;

它在 2-4 秒内运行(内部 SQL 仅针对这 300 个案例运行)。

于 2012-07-26T18:09:08.210 回答
0

一些改进:

SELECT MINIDS.USERID, USERNAME, PASSWORD, FULL_NAME, COUNTRY, EMAIL,
       (SELECT OPENCLIPART_FILES.ID
          FROM OPENCLIPART_FILES
         WHERE AVATAR LIKE '%svg' AND USERS.FILENAME = AVATAR) AS AVATAR, 
       HOMEPAGE, USERGROUP, NOTIFY, NSFWFILTER
  FROM     AIKI_USERS USERS
       INNER JOIN
           (SELECT MIN(USERID) AS USERID
              FROM AIKI_USERS
            GROUP BY USERNAME) MINIDS
       ON MINIDS.USERID = USERS.USERID;
于 2012-07-26T17:27:17.400 回答