SELECT citing.article_id as citing, lac_a.year, r.id_when_cited, cited_issue.country, citing.num_citations
FROM isi_lac_authored_articles as lac_a
JOIN isi_articles citing ON (lac_a.article_id = citing.article_id)
JOIN isi_citation_references r ON (citing.article_id = r.article_id)
JOIN isi_articles cited ON (cited.id_when_cited = r.id_when_cited)
JOIN isi_issues cited_issue ON (cited.issue_id = cited_issue.issue_id);
我在所有正在加入的字段上都有索引。
我能做些什么吗?我的表很大(大约1百万条记录,参考表有5亿条记录,文章表有2500万条记录)。
这就是EXPLAIN所说的:
+----+-------------+-------------+--------+--------------------------------------------------------------------------+---------------------------------------+---------+-------------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+--------------------------------------------------------------------------+---------------------------------------+---------+-------------------------------+---------+-------------+
| 1 | SIMPLE | cited_issue | ALL | NULL | NULL | NULL | NULL | 1156856 | |
| 1 | SIMPLE | cited | ref | isi_articles_id_when_cited,isi_articles_issue_id | isi_articles_issue_id | 49 | func | 19 | Using where |
| 1 | SIMPLE | r | ref | isi_citation_references_article_id,isi_citation_references_id_when_cited | isi_citation_references_id_when_cited | 17 | mimir_dev.cited.id_when_cited | 4 | Using where |
| 1 | SIMPLE | lac_a | eq_ref | PRIMARY | PRIMARY | 16 | mimir_dev.r.article_id | 1 | |
| 1 | SIMPLE | citing | eq_ref | PRIMARY | PRIMARY | 16 | mimir_dev.r.article_id | 1 | |
+----+-------------+-------------+--------+--------------------------------------------------------------------------+---------------------------------------+---------+-------------------------------+---------+-------------+
5 rows in set (0.07 sec)
答案 0 :(得分:0)
我认为这是你能做的最好的事情。我的意思是至少它不使用嵌套/多个查询。你应该对sql做一点基准测试。你至少可以限制你的结果。每页15-30行的返回集非常精细(这取决于应用程序,但对我来说15-30是容差范围)
我相信mySQL(phpMyAdmin,控制台,GUI等)他们会返回某种“执行时间”,这是查询处理所花费的时间。使用服务器端代码将其与查询基准进行比较。然后将其与使用服务器端代码运行的查询进行比较,然后将其与之后包含的应用程序界面一起输出。
通过这个,您可以看到瓶颈在哪里 - 这是您优化的地方。
答案 1 :(得分:0)
除非您的查询结果输入到某个其他查询或系统,否则返回那么多(3M)行是没用的。对于可视化,每个查询(如1000)只返回可接受的行数是很聪明的。
答案 2 :(得分:0)
查看您的SQL - 缺少WHERE子句意味着它将从以下行中提取所有行:
JOIN isi_issues cited_issue ON (cited.issue_id = cited_issue.issue_id)
您可以查看对大型isi_issues表进行分区,这样可以让MySQL执行得更快(较小的文件更容易处理)
或者你可以循环语句并使用LIMIT子句。
LIMIT 0,100000 然后 LIMIT 100001,200000
这将使语句更快地运行,您可以批量处理数据。
答案 3 :(得分:0)
如果你真的需要所有返回的数据,我会建议两件事:
您可能比MySQL更了解数据,如果MySQL的假设不正确,您可以尝试利用它。目前,MySQL认为在开始时更容易全面扫描整个isi_issues
表,如果结果确实包含所有问题,那么假设是正确的。但是,如果结果中不存在许多问题,您可能需要强制另一个您认为更正确的连接顺序。是你,谁知道哪个表适用最强的限制,哪个是最小的全扫描(你无论如何都需要完全扫描一些东西,因为没有WHERE子句)。
您可以从覆盖索引中获利(即索引本身包含足够的数据而不需要触及行数据)。例如,isi_articles
上的isi_lac_authored_articles
和({1}}上的(article_id,year)索引(article_id,num_citations)和isi_issues
上的偶数(国家/地区)将显着加快查询速度索引适合内存,但是,从另一方面来说,将使索引更大并且稍微减慢了表中的插入。