Correct MySQL table indexing

I can not get this request to execute faster than 8 hours ! 0_0 I read about indexing, and I'm still not sure if I am doing it right.

I expect my query to calculate a value for BROK_1_RATINGbased on dates and other string values ​​- 500,000 records .

Using record # 1 as an example - my request should:

  • get all other entries that have the same ESTIMID

  • ignore entries where ANALYST= ""

  • ignore records where IDmatches record matching, i.e. ID! = 1

  • Records must fall within the time frame i.e. BB. ANNDATS_CONVERTED<= working. ANNDATS_CONVERTED, BB. REVDATS_CONVERTED> working.ANNDATS_CONVERTED

  • BB. IRECCDmust = 1

  • Then count the result

  • Then write the count value to column BROK_1_RATING# 1

  • now doing the same for entries # 2 and # 3, etc. for the whole table

In human terms, β€œLearn the date of entry # 1.” Now, during the period of time from record No. 1, count the number of times that the number 1 exists with the same brokerage organization ESTIMID, do not consider record No. 1, do not read empty lines ANALYST. Go to entry # 2 and do the same "


UPDATE `working` SET `BROK_1_RATING` = 

    (SELECT COUNT(`ID`) FROM (SELECT `ID`, `IRECCD`, `ANALYST`,  `ESTIMID`, `ANNDATS_CONVERTED`, `REVDATS_CONVERTED` FROM `working`) AS BB 

        WHERE 
            BB.`ANNDATS_CONVERTED` <= `working`.`ANNDATS_CONVERTED` 
        AND 
            BB.`REVDATS_CONVERTED` > `working`.`ANNDATS_CONVERTED`
        AND 
            BB.`ID` != `working`.`ID`
        AND 
            BB.`ESTIMID` = `working`.`ESTIMID`
        AND
            BB.`ANALYST` != ''
        AND
            BB.`IRECCD` = 1
    )

WHERE `working`.`ANALYST` != '';

| ID | ANALYST |   ESTIMID    | IRECCD | ANNDATS_CONVERTED | REVDATS_CONVERTED |  BROK_1_RATING  | NO_TOP_RATING |  
------------------------------------------------------------------------------------------------------------------
| 1  |  DAVE   | Brokerage000 |   4    |    1998-07-01     |    1998-07-04     |                 |      3        |
| 2  |  DAVE   | Brokerage000 |   1    |    1998-06-28     |    1998-07-10     |                 |      4        |
| 3  |  DAVE   | Brokerage000 |   5    |    1998-07-02     |    1998-07-08     |                 |      2        |
| 4  |  DAVE   | Brokerage000 |   1    |    1998-07-04     |    1998-12-04     |                 |      3        |
| 5  |  SAM    | Brokerage000 |   1    |    1998-06-14     |    1998-06-30     |                 |      4        |
| 6  |  SAM    | Brokerage000 |   1    |    1998-06-28     |    1999-08-08     |                 |      4        |
| 7  |         | Brokerage000 |   1    |    1998-06-28     |    1999-08-08     |                 |      5        |
| 8  |  DAVE   | Brokerage111 |   2    |    1998-06-28     |    1999-08-08     |                 |      3        |

EXPLAIN :

id| select_type        | table            | type  | possible_keys | key                   | key_len | ref   | rows   | Extra
----------------------------------------------------------------------------------------------------------------------------------------
1 | PRIMARY            | working          | index | ANALYST       | PRIMARY               | 4       | NULL  | 467847 | Using where
2 | DEPENDENT SUBQUERY | <derived3>       | ALL   | NULL          | NULL                  | NULL    | NULL  | 467847 | Using where
3 | DERIVED            | working          | index | NULL          | test_combined_indexes | 226     | NULL  | 467847 | Using index

I have indexes for individual columns - and also - tried several columns, for example:

ALTER TABLE `working` ADD INDEX `test_combined_indexes` (`IRECCD`, `ID`, `ANALYST`, `ESTIMID`, `ANNDATS_CONVERTED`, `REVDATS_CONVERTED`) COMMENT '';
+4
source share
1 answer

Well, you can shorten the query by simply removing the excess material:

UPDATE `working` as AA SET `BROK_1_RATING` = 
(SELECT COUNT(`ID`) FROM `working` AS BB 
    WHERE BB.`ANNDATS_CONVERTED` <= AA.`ANNDATS_CONVERTED` 
    AND BB.`REVDATS_CONVERTED` > AA.`ANNDATS_CONVERTED`
    AND BB.`ID` != AA.`ID`
    AND BB.`ESTIMID` = AA.`ESTIMID`
    AND BB.`ANALYST` != ''
    AND BB.`IRECCD` = 1 )
WHERE `ANALYST` != '';
0
source

Source: https://habr.com/ru/post/1570347/


All Articles