1

挿入選択を呼び出したいのですが、この選択を使用しようとしています ( 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しか持っていません)。

そのアバターを openclipart_users にすばやく挿入する方法はありますか (数秒で INSERT SELECT を実行する必要はありません)。

Explain over SELECT のEDIT出力

+----+--------------------+-------------------+--- ---+---------------+----------+---------+------- ---------------------------+--------------------+------------- +
| | ID | select_type | テーブル | タイプ | 可能な_キー | キー | 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 | where | の使用
+----+--------------------+-------------------+--- ---+---------------+----------+---------+------- ---------------------------+--------------------+------------- +
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

@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 に答える
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 に答える
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 に答える