두 테이블 70,000 개의 항목이있는 표 A와 600,000 개의 항목이있는 표 B가 있습니다. 다음과 같이 구조는 다음과 같습니다이 MySQL 쿼리를 최적화하기위한 다른 방법이 있습니까?
표 A :
+-----------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| number | bigint(20) unsigned | YES | | NULL | |
+-----------+---------------------+------+-----+---------+----------------+
표 B :
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| number_s | bigint(20) unsigned | YES | MUL | NULL | |
| number_e | bigint(20) unsigned | YES | MUL | NULL | |
| source | varchar(50) | YES | | NULL | |
+-------------+---------------------+------+-----+---------+----------------+
내가 표 A의 값 중 하나를 사용하여 표 B에있는 경우 찾기 위해 노력하고있다 다음 코드 :
$sql = "SELECT number from TableA";
$result = mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_assoc($result)) {
$number = $row['number'];
$sql = "SELECT source, count(source) FROM TableB WHERE number_s < $number AND number_e > $number GROUP BY source";
$re = mysql_query($sql) or die(mysql_error);
while($ro = mysql_fetch_array($re)) {
echo $number."\t".$ro[0]."\t".$ro[1]."\n";
}
}
나는 쿼리가 빠르게 진행되기를 바랬지 만 어떤 이유로 그것은 끔찍하지 않다. 빨리.
mysql> explain SELECT source, count(source) FROM TableB WHERE number_s < 1812194440 AND number_e > 1812194440 GROUP BY source;
+----+-------------+------------+------+-------------------------+------+---------+------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+-------------------------+------+---------+------+--------+----------------------------------------------+
| 1 | SIMPLE | TableB | ALL | number_s,number_e | NULL | NULL | NULL | 696325 | Using where; Using temporary; Using filesort |
+----+-------------+------------+------+-------------------------+------+---------+------+--------+----------------------------------------------+
1 row in set (0.00 sec)
인가가 나는이 밖으로 짜낼 수있는 최적화 : ("수"의 특정 값) 선택에 설명 내 것은 다음 나에게 준다?
동일한 작업을 위해 저장 프로 시저를 작성했지만 처음부터 제대로 작동하지 않는 것 같습니다 ... 구문 오류가 없습니다 ... 하루 동안 실행 해 보았습니다. 이상하게 느껴지는 아직 달리고 있었다. 당신이 number_e
및 number_s
열에 대한 별도의 인덱스를 가지고있는 것처럼
CREATE PROCEDURE Filter()
Begin
DECLARE number BIGINT UNSIGNED;
DECLARE x INT;
DECLARE done INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT number FROM TableA;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
CREATE TEMPORARY TABLE IF NOT EXISTS Flags(number bigint unsigned, count int(11));
OPEN cur1;
hist_loop: LOOP
FETCH cur1 INTO number;
SELECT count(*) from TableB WHERE number_s < number AND number_e > number INTO x;
IF done = 1 THEN
LEAVE hist_loop;
END IF;
IF x IS NOT NULL AND x>0 THEN
INSERT INTO Flags(number, count) VALUES(number, x);
END IF;
END LOOP hist_loop;
CLOSE cur1;
END
나는 이것을 똑바로 만듭시다. 당신은 700,001 개의 쿼리를 실행 중입니다. 당신은 그것이 빠르지 않은 것에 놀랐습니까? – Thomas
글쎄 .. 나는 그다지 빠르지 않다는 말은하지 않고있다. 내가 더 빨리 할 수있는 최적화가 있는지 묻고있다. :) – Legend
'$ number BETWEEN number_s 및 number_e'? – extraneon