最快的方法是:
我现在做的事情:
我每秒输入大约60k-75k行,这还不够,但非常接近。我想要达到250.000行。
到目前为止还没有真正使用过。我得到20%的时间“网络I / O”块,有一个核心80%加载CPU端。光盘写出7mb-14mb,大部分是空闲的。 RAID 10上有6只猛禽的平均队列长度为...... 0.25。
任何人都知道如何加快速度?更快的服务器(到目前为止它是虚拟的,8GB RAM,4个核心,物理磁盘通过数据)。
添加一些说明:
垂直分区是否有帮助,例如通过一个字节(tinyint)来分割仪器世界,例如16个表格,我这样同时最多可以进行16次插入?实际上,数据来自不同的交易所,我可以为每个交易所制作一个分区。这将是一个自然的分割场(实际上是在乐器中,但我可以在这里复制这些数据)。
更多澄清:速度更高(90k),现在明显受到机器之间网络IO的限制,这可能是VM切换。
我现在所做的是每32k行进行一次连接,建立临时表,使用SqlBUlkdCopy插入,然后使用ONE sql语句复制到主表 - 最小化主表上的任何锁定时间。
现在大部分等待时间仍在网络IO上。似乎我遇到了VM明智的问题。将在未来几个月转向物理硬件;)
答案 0 :(得分:3)
如果你每秒管理70k行,那么到目前为止你很幸运。但我怀疑这是因为你有一个非常简单的架构。
我无法相信你在这个问题上提出这种负担
网络和CPU是共享的,IO受到限制:您无法使用所有资源。 您看到的任何负载统计数据都不是很有用。我怀疑您看到的网络负载是2个虚拟服务器之间的流量,如果您解决此问题,您将成为IO绑定
在继续之前,请阅读10 lessons from 35K tps。他没有使用虚拟盒子。
如果您想增加数量,假设没有SAN且没有DR功能,这就是我要做的事情。
作为参考,我们的峰值负载是每小时1200万行(16核,16GB,SAN,x64),但我们的负载复杂。我们没有能力。
答案 1 :(得分:1)
桌子上有没有你可以做的索引吗?编辑:在你打字的时候询问。
是否可以将价格转换为整数,然后除以1000或任何查询?
答案 2 :(得分:1)
您是否尝试过将pk添加到表中?这会提高速度吗?
还有一种基于集合的方法来使用计数表从http://www.sqlservercentral.com/articles/T-SQL/62867/导入csv数据(靠近底部,需要免费注册但值得)。
你可能想尝试一下并测试它的性能......用一个小的计数正确索引的计数表。
答案 3 :(得分:1)
从我在这里读到的答案来看,你似乎确实遇到了硬件问题,而不是代码问题。理想情况下,通过提供更多磁盘I / O或网络带宽,或者在托管数据库的同一虚拟机上运行程序,可以提高性能。
但是我确实想分享表参数插入非常适合大数据传输的想法;虽然SqlBulkCopy看起来同样快,但它的灵活性却大大降低。
我在这里写了一篇关于这个主题的文章:http://www.altdevblogaday.com/2012/05/16/sql-server-high-performance-inserts/
总的答案是你大致想要创建一个表类型:
CREATE TYPE item_drop_bulk_table_rev4 AS TABLE (
item_id BIGINT,
monster_class_id INT,
zone_id INT,
xpos REAL,
ypos REAL,
kill_time datetime
)
然后,您创建一个存储过程以直接从table参数复制到实际表中,因此中间步骤较少:
CREATE PROCEDURE insert_item_drops_rev4
@mytable item_drop_bulk_table_rev4 READONLY
AS
INSERT INTO item_drops_rev4
(item_id, monster_class_id, zone_id, xpos, ypos, kill_time)
SELECT
item_id, monster_class_id, zone_id, xpos, ypos, kill_time
FROM
@mytable
后面的SQL Server代码如下所示:
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("item_id", typeof(Int64)));
dt.Columns.Add(new DataColumn("monster_class_id", typeof(int)));
dt.Columns.Add(new DataColumn("zone_id", typeof(int)));
dt.Columns.Add(new DataColumn("xpos", typeof(float)));
dt.Columns.Add(new DataColumn("ypos", typeof(float)));
dt.Columns.Add(new DataColumn("timestamp", typeof(DateTime)));
for (int i = 0; i < MY_INSERT_SIZE; i++) {
dt.Rows.Add(new object[] { item_id, monster_class_id, zone_id, xpos, ypos, DateTime.Now });
}
// Now we're going to do all the work with one connection!
using (SqlConnection conn = new SqlConnection(my_connection_string)) {
conn.Open();
using (SqlCommand cmd = new SqlCommand("insert_item_drops_rev4", conn)) {
cmd.CommandType = CommandType.StoredProcedure;
// Adding a "structured" parameter allows you to insert tons of data with low overhead
SqlParameter param = new SqlParameter("@mytable", SqlDbType.Structured);
param.Value = dt;
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
}
}
答案 4 :(得分:1)
一切都很慢。
前段时间我们解决了一个类似的问题(插入数以万计的价格数据,因为我记得每个时间帧大约有50K,我们有大约8个时间帧都发生冲突:00,所以它是关于400K记录)它对我们来说非常快(MS SQL 2005)。想象一下今天它将如何运作(SQL 2012):
<...init...>
if(bcp_init(m_hdbc, TableName, NULL, NULL, DB_IN) == FAIL)
return FALSE;
int col_number = 1;
// Bind columns
if(bcp_bind(m_hdbc, (BYTE *)&m_sd.SymbolName, 0, 16, (LPCBYTE)"", 1, 0, col_number++) == FAIL) return FALSE;
if(bcp_bind(m_hdbc, (BYTE *)&m_sd.Time, 0, 4, 0, 0, 0, col_number++) == FAIL) return FALSE;
if(bcp_bind(m_hdbc, (BYTE *)&m_sd.Open, 0, 8, 0, 0, 0, col_number++) == FAIL) return FALSE;
if(bcp_bind(m_hdbc, (BYTE *)&m_sd.High, 0, 8, 0, 0, 0, col_number++) == FAIL) return FALSE;
if(bcp_bind(m_hdbc, (BYTE *)&m_sd.Low, 0, 8, 0, 0, 0, col_number++) == FAIL) return FALSE;
if(bcp_bind(m_hdbc, (BYTE *)&m_sd.Close, 0, 8, 0, 0, 0, col_number++) == FAIL) return FALSE;
if(bcp_bind(m_hdbc, (BYTE *)&m_sd.Volume, 0, 8, 0, 0, 0, col_number++) == FAIL) return FALSE;
<...save into sql...>
BOOL CSymbolStorage::Copy(SQL_SYMBOL_DATA *sd)
{
if(!m_bUseDB)
return TRUE;
memcpy(&m_sd, sd, sizeof(SQL_SYMBOL_DATA));
if(bcp_sendrow(m_hdbc) != SUCCEED)
return FALSE;
return TRUE;
}
答案 5 :(得分:0)
你能用水平分区吗? 请参阅:http://msdn.microsoft.com/en-us/library/ms178148.aspx&amp; http://msdn.microsoft.com/en-us/library/ms188706.aspx
您可能还想查看此问题,并可能更改恢复模型: Sql Server 2008 Tuning with large transactions (700k+ rows/transaction)
一些问题: 您使用的是哪个版本的SQL Server?
为什么一个核心为80%?这可能是瓶颈,所以可能值得研究。
你使用什么操作系统,是64位?