我有2张桌子:
书(身份证,头衔,年龄)----> 100亿行
作者(id,book_id,name,born)----> 1000万行
现在,假设我有一本书的通用ID.我需要打印这个页面:
Title: mybook
authors: Tom, Graham, Luis, Clarke, George
Run Code Online (Sandbox Code Playgroud)
那么......最好的方法是什么?
1)这样的简单连接:
Select book.title, author.name
From book, author
WHERE ( author.book_id = book.id ) AND ( book.id = 342 )
Run Code Online (Sandbox Code Playgroud)
2)为了避免加入,我可以做2个简单的查询:
Select title FROM book WHERE id = 342
Select name FROM author WHERE book_id = 342
Run Code Online (Sandbox Code Playgroud)
什么是最有效的方式?
我有一个400行的SQL查询,它会在30秒内抛出异常
ORA-03113:通信信道上的文件结束
以下是需要注意的事项:
令人不安的情况是这样的:
AND UPPER (someMultiJoin.someColumn) LIKE UPPER ('%90936%')
Run Code Online (Sandbox Code Playgroud)
所以我的假设是,查询从服务器端被终止,显然是因为它被识别为资源占用.
我的假设是否合适?我该如何解决这个问题呢?
编辑:我试图得到错误查询的解释计划,但解释计划查询也给我一个ORA-03113错误.我知道我的查询不是很高效,但为什么这是ORA-03113错误的原因.我试图从toad运行查询并且没有生成警报日志或跟踪,我的db版本是 Oracle9i企业版版本9.2.0.7.0 - 生产
我们开发了一个带有搜索屏幕的系统,看起来像这样:
http://demo1.nsourceservices.com/images/logos/stackoverflow1.png
如您所见,有一些相当严肃的搜索功能.您可以使用状态,渠道,语言,广告系列类型的任意组合,然后按名称等缩小范围.
然后,一旦您搜索并在底部弹出线索,您就可以对标题进行排序.
该查询使用ROWNUM来执行分页方案,因此我们一次只返回70行.
问题
即使我们只返回70行,也会进行大量的IO和排序.这当然是有道理的.
这总是会给磁盘队列带来一些小的尖峰.当我们达到300万个潜在客户时,它开始放慢速度,现在我们已经接近5,磁盘队列有时会挂起一两秒或两个.
这实际上仍然是可行的,但是这个系统还有另一个区域,它有一个时间敏感的过程,简单地说,它是一个Web服务,需要非常快速地提供响应,否则会导致另一端超时.磁盘队列峰值导致该部分陷入停滞,这导致下游超时.最终的结果实际上是我们基于VoiceXML的自动IVR中的电话掉线,这对我们来说非常糟糕.
我们尝试过什么
我们尝试过:
在结束...
我的一部分感觉服务器应该能够处理这个问题.鉴于该服务器的强大功能,五百万条记录并不是那么多,这是一个体面的四核,有16个内存.但是,我可以看到排序部分如何触及数百万行只是为了返回少数几行.
那么你在这样的情况下做了什么?我的直觉是我们应该削减一些功能,但是如果有一种方法可以保持这种完整性,这将节省我与业务部门的战争.
提前致谢!
当我试图解决一个更复杂的问题时,我遇到了这个小问题,并试图找出优化器.所以,假设我有一个名为`MyTable'的表,可以像这样定义:
CREATE TABLE MyTable (
GroupClosuresID int identity(1,1) not null,
SiteID int not null,
DeleteDateTime datetime null
, CONSTRAINT PK_MyTable PRIMARY KEY (GroupClosuresID, SiteID))
Run Code Online (Sandbox Code Playgroud)
该表中有286,685行,运行DBCC SHOW_STATISTICS('MyTable','PK_MyTable')将产生:
Name Updated Rows Rows Sampled Steps Density Average key length String Index Filter Expression Unfiltered Rows
-------------------------------------------------------------------------------------------------------------------------------- -------------------- -------------------- -------------------- ------ ------------- ------------------ ------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------
PK_MyTable Aug 10 2011 1:00PM 286685 286685 18 0.931986 8 NO NULL 286685
(1 row(s) affected)
All density Average Length Columns
------------- -------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3.743145E-06 4 …Run Code Online (Sandbox Code Playgroud) 我有以下查询:
SELECT ID, ADDRESS
FROM EMPLOYEE A
WHERE ID=12345
AND CURRENT DATE BETWEEN A.EFF_DT AND A.EXP_DT
SELECT ID, ADDRESS
FROM EMPLOYEE A
WHERE ID=12345
AND CURRENT DATE >= A.EFF_DT AND CURRENT DATE <= A.EXP_DT
Run Code Online (Sandbox Code Playgroud)
在这两个查询中,查询产生更好的性能.
这里我使用运算符> =和<=而不是BETWEEN.
请建议.
提前致谢.
通过sqlite文档阅读,我发现了以下功能:
http://www.sqlite.org/lang_corefunc.html#likelihood
似然(X,Y)函数返回参数X不变.似然值Y(X,Y)必须是0.0到1.0之间的浮点常数,包括0.0和1.0.似然(X)函数是代码生成器优化掉的无操作,因此它在运行时(即调用sqlite3_step()期间)不消耗CPU周期.似然(X,Y)函数的目的是向查询规划器提供一个提示,即参数X是一个布尔值,其概率为大约为Y.不太可能的(X)函数是可能性的简写( X,0.0625).
假设我知道1将返回75%的时间,那么将如何:
select likelihood(x,.75)
Run Code Online (Sandbox Code Playgroud)
帮助查询优化器?
我有以下查询:
SELECT
SUM("balance_transactions"."fee") AS sum_id
FROM "balance_transactions"
JOIN charges ON balance_transactions.source = charges.balance_id
WHERE "balance_transactions"."account_id" = 6
AND (balance_transactions.type = 'charge'
AND charges.refunded = false
AND charges.invoice IS NOT NULL)
AND ("balance_transactions"."created" BETWEEN '2013-12-20' AND '2014-01-19');
Run Code Online (Sandbox Code Playgroud)
这样做会增加这两个日期之间发生的所有"费用".大.工作良好.
问题是我几乎总是一次需要数百个日期范围的费用,这相当于我运行相同的查询数百次.效率不高.
但有没有办法将其压缩为所有日期范围的单个查询?
例如,我要求SUM一系列这样的范围:
2013-12-20 to 2014-01-19
2013-12-21 to 2014-01-20
2013-12-22 to 2014-01-21
2013-12-23 to 2014-01-22
2013-12-24 to 2014-01-23
...so on and so on
Run Code Online (Sandbox Code Playgroud)
我需要输出在每个日期范围内收集的费用总和(最终需要在数组中).
那么,关于处理和减少数据库事务的方法的任何想法?
FWIW,这是在Rails应用程序内的Postgres上.
我有一个基于3列的复合索引,其中两列在我的查询中受约束,第三列是按顺序子句,但mysql不使用索引进行排序.
explain select * from videos where public_private='public' and approved='yes' order by number_of_views desc; +----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ | 1 | SIMPLE | videos | ALL | approved,approved_3,approved_2 | NULL | NULL | NULL | 1476818 | Using where; Using filesort | +----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+
表结构如下:
CREATE TABLE `videos` (
`indexer` int(9) NOT NULL auto_increment,
`user_id` int(9) default NULL,
`public_private` varchar(24) default NULL, …Run Code Online (Sandbox Code Playgroud) 我有一个使用以下架构的数据库:
CREATE TABLE IF NOT EXISTS `sessions` (
`starttime` datetime NOT NULL,
`ip` varchar(15) NOT NULL default '',
`country_name` varchar(45) default '',
`country_iso_code` varchar(2) default '',
`org` varchar(128) default '',
KEY (`ip`),
KEY (`starttime`),
KEY (`country_name`)
);
Run Code Online (Sandbox Code Playgroud)
(实际表包含更多列;我只包含我查询的列。)引擎是 InnoDB。
正如您所看到的,有 3 个索引 - ip、starttime和country_name。
该表非常大 - 它包含大约 150 万行。我正在对其运行各种查询,尝试提取一个月的信息(2018 年 8 月,在下面的示例中)。
像这样的查询
SELECT
UNIX_TIMESTAMP(starttime) as time_sec,
country_iso_code AS metric,
COUNT(country_iso_code) AS value
FROM
sessions
WHERE
starttime >= FROM_UNIXTIME(1533070800) AND
starttime <= FROM_UNIXTIME(1535749199)
GROUP BY …Run Code Online (Sandbox Code Playgroud) 我正在使用数据库客户端来测试。
使用EXPLAIN ANALYZE:
Hash Join (cost=5.02..287015.54 rows=3400485 width=33) (actual time=0.023..1725.842 rows=3327845 loops=1)
Hash Cond: ((fact_orders.financial_status)::text = (include_list.financial_status)::text)
CTE include_list
-> Result (cost=0.00..1.77 rows=100 width=32) (actual time=0.003..0.004 rows=4 loops=1)
-> ProjectSet (cost=0.00..0.52 rows=100 width=32) (actual time=0.002..0.003 rows=4 loops=1)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.000..0.000 rows=1 loops=1)
-> Seq Scan on fact_orders (cost=0.00..240253.85 rows=3400485 width=38) (actual time=0.006..551.558 rows=3400485 loops=1)
-> Hash (cost=2.00..2.00 rows=100 width=32) (actual time=0.009..0.009 rows=4 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> CTE Scan on …Run Code Online (Sandbox Code Playgroud) sql postgresql query-optimization explain sql-execution-plan