我们在使用特定的SQL查询时遇到性能问题,我们正在尝试找出如何在此处进行改进。它的执行时间大约是20-100秒!
这是查询,并进行了解释:
SELECT "jobs".* FROM "jobs"
WHERE "jobs"."status" IN (1, 2, 3, 4)
ORDER BY "jobs"."due_date" ASC
LIMIT 5;
Limit (cost=0.42..1844.98 rows=5 width=2642) (actual time=16927.150..18151.643 rows=1 loops=1)
-> Index Scan using index_jobs_on_due_date on jobs (cost=0.42..1278647.41 rows=3466 width=2642) (actual time=16927.148..18151.641 rows=1 loops=1)
Filter: (status = ANY ('{1,2,3,4}'::integer[]))
Rows Removed by Filter: 595627
Planning time: 0.205 ms
Execution time: 18151.684 ms
我们在AWS RDS上使用PostgreSQL 9.6.11。
在一个表中,我们有约50万行。实现查询的字段为:
我们有以下索引:
CREATE INDEX index_jobs_on_due_date ON public.jobs USING btree (due_date)
CREATE INDEX index_jobs_on_due_date_and_status ON public.jobs USING btree (due_date, status)
CREATE INDEX index_jobs_on_status ON public.jobs USING btree (status)
CREATE UNIQUE INDEX jobs_pkey ON public.jobs USING btree (id)
预先感谢您, -杰克
答案 0 :(得分:1)
对于此查询:
access_token = dataset.iloc[0].to_frame()
“明显”索引位于 Table1.Rows.Clear();
List<Knjiga> knjige = new List<Knjiga>();
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("biblioteka.xml"));
foreach (XmlElement el in doc.GetElementsByTagName("knjiga"))
{
knjige.Add(new Knjiga()
{
ISBN = el.GetAttribute("ISBN"),
Naslov = el.GetAttribute("naslov"),
Stanje = Int32.Parse(el.GetAttribute("stanje")),
Citano = Int32.Parse(el.GetAttribute("citano"))
});
}
knjige = knjige.OrderByDescending(d => d.Citano).ToList();
foreach (var knjiga in knjige)
{
TableRow tr = new TableRow();
// Cells
TableCell isbn = new TableCell();
TableCell naslov = new TableCell();
TableCell stanje = new TableCell();
TableCell citano = new TableCell();
isbn.Text = knjiga.ISBN;
naslov.Text = knjiga.Naslov;
stanje.Text = knjiga.Stanje.ToString();
citano.Text = knjiga.Citano.ToString();
tr.Cells.AddRange(new TableCell[]{ isbn, naslov, stanje, citano});
Table1.Rows.Add(tr);
}
上。但这可能无济于事。目标是摆脱排序。因此,您可以重写查询并使用索引SELECT j.*
FROM "jobs" j
WHERE j."status" IN (1, 2, 3, 4)
ORDER BY "jobs"."due_date" ASC
LIMIT 5;
:
(status)
每个子查询都应使用复合索引。然后,最后的排序将是(最多)20行,这应该很快)。
编辑:
这里是一个相关的想法,具有相同的索引:
jobs(status, due_date)
这可以将索引用于select j.*
from ((select j.*
from jobs j
where j.status = 1
order by j.due_date asc
limit 5
) union all
(select j.*
from jobs j
where j.status = 2
order by j.due_date asc
limit 5
) union all
(select j.*
from jobs j
where j.status = 3
order by j.due_date asc
limit 5
) union all
(select j.*
from jobs j
where j.status = 4
order by j.due_date asc
limit 5
)
) j
order by due_date
limit 5;
计算。这可能需要对表进行全表扫描。但是,最终排序将限制为20行,因此消除了最终排序。