Come accelerare l'inserto Seleziona con Join Over String
-
12-12-2019 - |
Domanda
Voglio chiamare Inserisci Seleziona e provo a utilizzare questo selezione (con Guida da questo Inserisci query Seleziona quando una colonna è univoca )
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;
.
Lo uso con inserto
INSERT INTO openclipart_users(id, user_name, password, full_name, country,
email, avatar, homepage, user_group, notify, nsfw_filter) SELECT ...
.
Ci vuole molto tempo da eseguire (lo cancello dopo pochi minuti)
Aiki_USERS Tabella ha righe 100k e openclipart_files hanno righe 30k, in pratica ho appena copiato tutte le cose da Aiki_USer a OpenClipart_USERS che salta duplicati e voglio che Avatar sia id del file in cui nella vecchia tabella è una stringa (solo circa 300 utenti hanno svgAvatar su 1k utenti hanno non '' Avatar ma sono solo ciò che svg).
C'è un modo per inserire rapidamente quel avatar (senza che si inserisce selezionare Esegui in pochi secondi) in openclipart_USer, qualsiasi solubilità che funzionerà andrà bene (con rapidamente intendo meno un minuto).
Modifica Uscita di spiegazione su Seleziona
+----+--------------------+-------------------+--------+---------------+----------+---------+----------------------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------------------+--------+---------------+----------+---------+----------------------------------+--------+-------------+
| 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 106689 | |
| 1 | PRIMARY | users | eq_ref | PRIMARY | PRIMARY | 4 | minids.userid | 1 | |
| 3 | DERIVED | aiki_users | index | NULL | username | 302 | NULL | 111273 | Using index |
| 2 | DEPENDENT SUBQUERY | openclipart_files | ALL | NULL | NULL | NULL | NULL | 37715 | |
| 2 | DEPENDENT SUBQUERY | aiki_users | eq_ref | PRIMARY | PRIMARY | 4 | openclipart_staging.users.userid | 1 | Using where |
+----+--------------------+-------------------+--------+---------------+----------+---------+----------------------------------+--------+-------------+
.
Soluzione
Conversione per unire solo la sintassi (sbarazzarsi della sottosttrazione correlata e che si unisce a una sottosezione invece):
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
.
Provalo.
Altri suggerimenti
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
. Utilizzo del suggerimento da @spFiredRake con custodia e a destra creo questa query
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;
.
che funzionano in 2-4 secondi (SQL interni è stato eseguito solo per quei casi 300).
Alcuni miglioramenti:
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;
.