- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当表很小时,此查询有合理的时间。我试图确定瓶颈是什么,但我不确定如何分析 EXPLAIN
结果。
SELECT
COUNT(*)
FROM performance_analyses
INNER JOIN total_sales ON total_sales.id = performance_analyses.total_sales_id
WHERE
(size > 0) AND
total_sales.customer_id IN (
SELECT customers.id FROM customers WHERE customers.active = 't'
AND customers.visible = 't' AND customers.organization_id = 3
) AND
total_sales.product_category_id IN (
SELECT product_categories.id FROM product_categories
WHERE product_categories.organization_id = 3
) AND
total_sales.period_id = 193;
customers
的两种方法和
product_categories
表并进行内部选择。两人有相同的时间。
PostgreSQL 9.4.5 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-16), 64-bit
CREATE TABLE total_sales (
id serial NOT NULL,
value double precision,
start_date date,
end_date date,
product_category_customer_id integer,
created_at timestamp without time zone,
updated_at timestamp without time zone,
processed boolean,
customer_id integer,
product_category_id integer,
period_id integer,
CONSTRAINT total_sales_pkey PRIMARY KEY (id)
);
CREATE INDEX index_total_sales_on_customer_id ON total_sales (customer_id);
CREATE INDEX index_total_sales_on_period_id ON total_sales (period_id);
CREATE INDEX index_total_sales_on_product_category_customer_id ON total_sales (product_category_customer_id);
CREATE INDEX index_total_sales_on_product_category_id ON total_sales (product_category_id);
CREATE INDEX total_sales_product_category_period ON total_sales (product_category_id, period_id);
CREATE INDEX ts_pid_pcid_cid ON total_sales (period_id, product_category_id, customer_id);
CREATE TABLE performance_analyses (
id serial NOT NULL,
total_sales_id integer,
status_id integer,
created_at timestamp without time zone,
updated_at timestamp without time zone,
size double precision,
period_size integer,
nominal_variation double precision,
percentual_variation double precision,
relative_performance double precision,
time_ago_max integer,
deseasonalized_series text,
significance character varying,
relevance character varying,
original_variation double precision,
last_level double precision,
quantiles text,
range text,
analysis_method character varying,
CONSTRAINT performance_analyses_pkey PRIMARY KEY (id)
);
CREATE INDEX index_performance_analyses_on_status_id ON performance_analyses (status_id);
CREATE INDEX index_performance_analyses_on_total_sales_id ON performance_analyses (total_sales_id);
CREATE TABLE product_categories (
id serial NOT NULL,
name character varying,
organization_id integer,
created_at timestamp without time zone,
updated_at timestamp without time zone,
external_id character varying,
CONSTRAINT product_categories_pkey PRIMARY KEY (id)
);
CREATE INDEX index_product_categories_on_organization_id ON product_categories (organization_id);
CREATE TABLE customers (
id serial NOT NULL,
name character varying,
external_id character varying,
region_id integer,
organization_id integer,
created_at timestamp without time zone,
updated_at timestamp without time zone,
active boolean DEFAULT false,
visible boolean DEFAULT false,
segment_id integer,
"group" boolean,
group_id integer,
ticket_enabled boolean DEFAULT true,
CONSTRAINT customers_pkey PRIMARY KEY (id)
);
CREATE INDEX index_customers_on_organization_id ON customers (organization_id);
CREATE INDEX index_customers_on_region_id ON customers (region_id);
CREATE INDEX index_customers_on_segment_id ON customers (segment_id);
最佳答案
您的查询,重写和 100 % 等效:
SELECT count(*)
FROM product_categories pc
JOIN customers c USING (organization_id)
JOIN total_sales ts ON ts.customer_id = c.id
JOIN performance_analyses pa ON pa.total_sales_id = ts.id
WHERE pc.organization_id = 3
AND c.active -- boolean can be used directly
AND c.visible
AND ts.product_category_id = pc.id
AND ts.period_id = 193
AND pa.size > 0;
FROM
中的连接子句和顺序表中。列表。这可能适用于具有相对原始查询计划器的某个其他 RDBMS。但是,虽然它对 Postgres 也没有什么坏处,但它对查询的性能也没有影响——假设是默认的服务器配置。
The manual:
Explicit inner join syntax (
INNER JOIN
,CROSS JOIN
, or unadornedJOIN
) is semantically the same as listing the input relations inFROM
, so it does not constrain the join order.
join_collapse_limit
(默认为 8)。 Postgres 查询计划器将以任何它期望最快的方式重新排列您的 4 个表,无论您如何排列表以及是否将条件写为
WHERE
或
JOIN
条款。没有任何区别。 (对于其他一些不能自由重新排列的连接类型,情况并非如此。)
The important point is that these different join possibilities give semantically equivalent results but might have hugely different execution costs. Therefore, the planner will explore all of them to try to find the most efficient query plan.
WHERE id IN (<subquery>)
通常不等同于连接。它不会将左侧的行乘以右侧的重复匹配值。并且子查询的列对于查询的其余部分不可见。连接可以将具有重复值的行相乘,并且列是可见的。
IN (<subquery>)
通常(至少有点)更慢且更冗长。使用连接。
product_categories
有 34 行。除非您计划添加更多,否则索引不会帮助该表的性能。顺序扫描总是更快。放下
index_product_categories_on_organization_id
.
customers
有 6,970 行。索引开始变得有意义。但是根据
EXPLAIN
,您的查询使用了其中的 4,988 个。输出。只有
index-only scan在比表格小得多的索引上可能会有所帮助。假设
WHERE active AND visible
是常量谓词,我建议使用部分多列索引:
CREATE INDEX index_customers_on_organization_id ON customers (organization_id, id)
WHERE active AND visible;
id
允许仅索引扫描。否则,该列在此查询的索引中是无用的。
total_sales
有 7,104,441 行。索引非常重要。我建议:
CREATE INDEX index_total_sales_on_product_category_customer_id
ON total_sales (period_id, product_category_id, customer_id, id)
index_total_sales_on_product_category_id
.
performance_analyses
有 1,012,346 行。索引非常重要。
size > 0
的另一个部分索引:
CREATE INDEX index_performance_analyses_on_status_id
ON performance_analyses (total_sales_id)
WHERE pa.size > 0;
Rows Removed by Filter: 0"
size > 0
的行是不是真的?
ANALYZE
table 。
performance_analyses
和
total_sales
.
VACUUM
和
ANALYZE
,这使查询变慢,
according to your comment .这没有多大意义。我会跑
VACUUM FULL
在这两个表上一次(如果你能负担得起排他锁)。其他尝试
pg_repack
.
vacuumdb -fz yourdb
在你的数据库上。这会在原始条件下重写所有表和索引,但定期使用并不好。它也很昂贵,并且会长时间锁定您的数据库!
关于sql - 依靠条件连接大表的速度很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38235142/
可以创建许多内存密集型对象,然后放弃对它们的引用。例如,我可能想从数据库中下载某些数据并对其进行操作,我将进行100次单独的下载和处理迭代。我可以一次声明一个DataTable变量,然后对于每个查询,
当我运行这个查询时,我该怎么做才能做到这一点。 SELECT distinct cus_areacode AS "Area Code", cus_code AS "Number" FROM CUSTO
假设我有一个随机的 zend_db_select 对象。 我如何对该对象进行计数,以便知道满足查询的项目数量。 我尝试了以下方法: $data->TotalRecords = $select->col
我有几个流依赖于在一个流中生成然后传递给另一个流的 session 变量。依赖两个异步流使用的 session 变量是否安全?我想我没有完全理解 mule 应用程序或给定 mule 消息中“sessi
我有一个代表两个用户之间交易的模型,如下所示: class Transaction(models.Model): buyer = models.ForeignKey( Pers
我一直在浏览DeHL repository on GoogleCode ,对我来说看起来真的很好。 许多有趣的功能使基本的编程任务变得更加容易; DotNet FCL 中存在但 Delphi RTL
我正在构建一个包含产品的网站,每个产品都属于一个或多个类别,这些类别可以嵌套在父类别中。我想要 SEO 友好的 URL,如下所示: mysite.com/category/ mysite.com/ca
我有一个超过 7500 万行的 RDD,当我对其调用 count 函数时,我每次都会得到不同的数字。我的理解是 count 应该给出确切的数字。 编辑 只是为了给出数据的概念,结构是这样的 Useri
我想使用以下两个(简化的)表格来计算每个用户访问我的网站的唯一天数: Table: Users +--------------+------------------+ | Field |
我有三个表: users 只有两列:id: INT, name: TEXT houses 三列:id: INT, user_id: INT, sold_at: DATE users_with_hous
我的应用程序偶尔会遇到死锁,因为两个事务需要更新相同的行但顺序不同(例如,事务 A 更新行 X 然后 Y,而事务 B 更新行 Y 然后 X)。 由于各种原因,解决避免此类死锁的传统方法(锁定或以一致的
在这个示例程序中,我使用 strtok_r 将一个字符串拆分为两个标记。 #include #include int main(void) { char buf[] = "Hello Wo
Windows 句柄有时很烦人,要记得在之后进行清理(使用创建的笔和画笔进行 GDI 就是一个很好的例子)。 RAII 解决方案很棒,但是为每种不同类型的 handle 制作一个完整的(五法则)RAI
我了解到 NSUbiquitousKeyValueStore 始终可用,在 no iCloud account 时也是如此已成立。这让我相信我可以安全地将基本数据存储在其中,而无需在 NSUserDe
我正在创建一个新的 DataFrame,其中包含来自 Join 的少量记录。 val joined_df = first_df.join(second_df, first_df.col("key")
我一直在疯狂地创建单元测试,并发现我经常不得不在一个测试中设置一些我刚刚在之前的测试中删除的东西。在一次测试(例如插入测试)中创建某些内容(例如数据库记录)然后将其用于以后的测试(例如删除测试)是否合
我有一个 user_entry 表,其中包含一个date 字段。数据类型是日期时间。数据库是mysql。我想要当前日期和当前月份以及当前日期的所有数据的计数。 我怎样才能得到这个? 我尝试了以下查询,
我正在使用 Rob Conery 的 Massive ORM。 有没有一种优雅的方法来计算返回的记录集? dynamic viewModelExpando = result.ViewData.Mode
在 spark Dataframe 上获得计数的最佳方法是什么? 1) 我试过 count 会添加一个 Action 。但我不想添加额外的操作。 2) 我在 RDD 上使用了累加器,为此数据帧需要转换
我有两个类 Quiz{ String name static hasMany[tags:Tag] } Tag{ String tag } 如何使用标准构建器在 grails 中编写以下
我是一名优秀的程序员,十分优秀!