我有一张桌子
| base_schedule_line_items | CREATE TABLE
base_schedule_line_items
(
id
int(10) unsigned NOT NULL AUTO_INCREMENT,
installment
int(10) unsigned NOT NULL,
on_date
date NOT NULL,
actual_date
date DEFAULT NULL,
payment_type
int(11) NOT NULL,
scheduled_principal_outstanding
decimal(65,0) NOT NULL,
scheduled_principal_due
decimal(65,0) NOT NULL,
scheduled_interest_outstanding
decimal(65,0) NOT NULL,
scheduled_interest_due
decimal(65,0) NOT NULL,
currency
int(11) NOT NULL,
updated_at
datetime NOT NULL DEFAULT '2013-01-06 14:29:16',
created_at
datetime NOT NULL DEFAULT ' 2013-01-06 14:29:16',
loan_base_schedule_id
int(10) unsigned NOT NULL,
lending_id
int(10) unsigned NOT NULL,
reschedule
tinyint(1) DEFAULT '0', …
我正在运行一个查询,它有数十万条记录,获取数据需要 20 多分钟。运行执行计划后,我注意到聚集索引查找成本可能是原因。如何减少下面提到的查询的聚集索引查找成本?
外键的成本约为 13% 到 23%。
CREATE PROC [dbo].[Test] (@UserTypeID INT,
@UserID INT,
@CityID INT,
@OperatorID INT,
@ParameterID INT)
AS
BEGIN
DECLARE @temp TABLE (
range DECIMAL(18, 2),
range2 DECIMAL(18, 2),
image VARCHAR(50),
symbol VARCHAR(20))
IF( @UserID > 0 )
BEGIN
--print 'hii'
INSERT INTO @temp
(range,
range2,
image,
symbol)
SELECT tbl_Legend_ViewNetwork_Dtls.range,
tbl_Legend_ViewNetwork_Dtls.range2,
tbl_Legend_ViewNetwork_Dtls.image,
tbl_Legend_ViewNetwork_Dtls.symbol
FROM tbl_Legend_ViewNetwork_Dtls
INNER JOIN tbl_Legend_ViewNetwork
ON tbl_Legend_ViewNetwork_Dtls.tbl_legend_view_network_id = tbl_Legend_ViewNetwork.id
WHERE tbl_Legend_ViewNetwork.parameter_id = @ParameterID
AND tbl_Legend_ViewNetwork.user_type_id = @UserTypeID
AND tbl_Legend_ViewNetwork.is_default = 1
AND tbl_Legend_ViewNetwork.user_id = …
Run Code Online (Sandbox Code Playgroud) 我有许多列存储数据,这些数据可能包含一些用于格式化/分组的额外字符。想想电话号码和车牌号码等数据中的空白和破折号。
查询时,我们无法确定这些破折号是否存在以及在哪里存在,因此我们需要将它们从列中剥离。在查询时这样做对性能不利,所以我想为剥离的列创建一个计算列并在其上放置一个索引。
-- trimming the length down to 50 characters
-- which is the length of the original field
ALTER TABLE foo
ADD search_license_plate AS (LEFT(REPLACE(license_plate, '-', ''), 50));
CREATE INDEX ix_foo_search_license_plate ON foo(search_license_plate);
Run Code Online (Sandbox Code Playgroud)
这些计算列总是精确的,因此它们不需要因为缺乏精度而被持久化。
数据通常只输入一次并且很少被更改。从不大量使用,所以我不太关心持久化列的任何性能影响。
此外,计算列永远不会从查询中返回;它只会在查询条件中使用,通常
SELECT
foo.id,
foo.license_plate
FROM foo
WHERE foo.search_license_plate LIKE '%bar%';
Run Code Online (Sandbox Code Playgroud)
...虽然我不能保证SELECT *
这些表上没有完成。
是否需要保留这些列?