MySQL - SELECT WHERE field IN (subquery) - Extremely slow why?

前端 未结 10 2054
情书的邮戳
情书的邮戳 2020-11-27 10:06

I\'ve got a couple of duplicates in a database that I want to inspect, so what I did to see which are duplicates, I did this:

SELECT relevant_field
FROM some         


        
相关标签:
10条回答
  • 2020-11-27 10:29

    Subqueries vs joins

    http://www.scribd.com/doc/2546837/New-Subquery-Optimizations-In-MySQL-6

    0 讨论(0)
  • 2020-11-27 10:31

    sometimes when data grow bigger mysql WHERE IN's could be pretty slow because of query optimization. Try using STRAIGHT_JOIN to tell mysql to execute query as is, e.g.

    SELECT STRAIGHT_JOIN table.field FROM table WHERE table.id IN (...)
    

    but beware: in most cases mysql optimizer works pretty well, so I would recommend to use it only when you have this kind of problem

    0 讨论(0)
  • 2020-11-27 10:32

    This is similar to my case, where I have a table named tabel_buku_besar. What I need are

    1. Looking for record that have account_code='101.100' in tabel_buku_besar which have companyarea='20000' and also have IDR as currency

    2. I need to get all record from tabel_buku_besar which have account_code same as step 1 but have transaction_number in step 1 result

    while using select ... from...where....transaction_number in (select transaction_number from ....), my query running extremely slow and sometimes causing request time out or make my application not responding...

    I try this combination and the result...not bad...

    `select DATE_FORMAT(L.TANGGAL_INPUT,'%d-%m-%y') AS TANGGAL,
          L.TRANSACTION_NUMBER AS VOUCHER,
          L.ACCOUNT_CODE,
          C.DESCRIPTION,
          L.DEBET,
          L.KREDIT 
     from (select * from tabel_buku_besar A
                    where A.COMPANYAREA='$COMPANYAREA'
                          AND A.CURRENCY='$Currency'
                          AND A.ACCOUNT_CODE!='$ACCOUNT'
                          AND (A.TANGGAL_INPUT BETWEEN STR_TO_DATE('$StartDate','%d/%m/%Y') AND STR_TO_DATE('$EndDate','%d/%m/%Y'))) L 
    INNER JOIN (select * from tabel_buku_besar A
                         where A.COMPANYAREA='$COMPANYAREA'
                               AND A.CURRENCY='$Currency'
                               AND A.ACCOUNT_CODE='$ACCOUNT'
                               AND (A.TANGGAL_INPUT BETWEEN STR_TO_DATE('$StartDate','%d/%m/%Y') AND STR_TO_DATE('$EndDate','%d/%m/%Y'))) R ON R.TRANSACTION_NUMBER=L.TRANSACTION_NUMBER AND R.COMPANYAREA=L.COMPANYAREA 
    LEFT OUTER JOIN master_account C ON C.ACCOUNT_CODE=L.ACCOUNT_CODE AND C.COMPANYAREA=L.COMPANYAREA 
    ORDER BY L.TANGGAL_INPUT,L.TRANSACTION_NUMBER`
    
    0 讨论(0)
  • 2020-11-27 10:36

    Firstly you can find duplicate rows and find count of rows is used how many times and order it by number like this;

    SELECT q.id,q.name,q.password,q.NID,(select count(*) from UserInfo k where k.NID= q.NID) as Count,
    (
    		CASE q.NID
    		WHEN @curCode THEN
    			@curRow := @curRow + 1
    		ELSE
    			@curRow := 1
    		AND @curCode := q.NID
    		END
    	) AS No
    FROM UserInfo q,
    (
    		SELECT
    			@curRow := 1,
    			@curCode := ''
    	) rt
    WHERE q.NID IN
    (
        SELECT NID
        FROM UserInfo
        GROUP BY NID
        HAVING COUNT(*) > 1
    ) 

    after that create a table and insert result to it.

    create table CopyTable 
    SELECT q.id,q.name,q.password,q.NID,(select count(*) from UserInfo k where k.NID= q.NID) as Count,
    (
    		CASE q.NID
    		WHEN @curCode THEN
    			@curRow := @curRow + 1
    		ELSE
    			@curRow := 1
    		AND @curCode := q.NID
    		END
    	) AS No
    FROM UserInfo q,
    (
    		SELECT
    			@curRow := 1,
    			@curCode := ''
    	) rt
    WHERE q.NID IN
    (
        SELECT NID
        FROM UserInfo
        GROUP BY NID
        HAVING COUNT(*) > 1
    ) 

    Finally, delete dublicate rows.No is start 0. Except fist number of each group delete all dublicate rows.

    delete from  CopyTable where No!= 0;

    0 讨论(0)
提交回复
热议问题