我注意到 SSMS (SQL Server Management Studio 2016),查询结果会在一秒钟内返回(超过10k +行)。结果表/网格滚动非常流畅,并且在SSMS上具有极低的内存占用(~80MB)。这种类似网格/视图的控制方式可以执行ListView(~200MB,2-3秒)和DataGrid(~600MB,8-10秒)。即使我关闭所有可视化或调整cancententscroll或修改它的高度以优化速度,它们仍然在SSMS中远远落后于网格,仍然使用缓慢的滚动和GUI操作。
SSMS中使用的网格控制背后是什么让它如此流畅?
答案 0 :(得分:21)
SSMS网格不是C ++,它不是ListView,也不是DataGrid,它不使用Windows本机控件,它只是一个名为GridControl
的自定义.NET控件(在Microsoft.SqlServer.Management.UI.Grid
命名空间中)属于名为Microsoft.SqlServer.GridControl.dll的程序集。
您可以在各个地方找到它:GAC,%ProgramFiles(x86)%\Common Files\Microsoft Shared\SQL Server Developer Tools
,Visual Studio文件等。
它不是可再发行的二进制AFAIK,所以你不应该发布它,它没有记录,并且它不像其他人那样是一个功能齐全的网格。但是,正如您所发现的那样,它是轻量级的,并且可以快速,与基础数据访问一样快。
如果你想玩它,这里有一个小的Winforms C#样本(10000 x 256网格,即250万个立即打开的单元格),演示了如何使用它:
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.SqlServer.Management.UI.Grid;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private GridControl _control = new GridControl();
public Form1()
{
InitializeComponent();
for (int i = 0; i < 256; i++)
{
_control.AddColumn(new GridColumnInfo { HeaderType = GridColumnHeaderType.Text, IsUserResizable = true });
_control.SetHeaderInfo(i, "Column " + i, null);
}
_control.Dock = DockStyle.Fill;
_control.GridStorage = new GridStorage();
Controls.Add(_control);
}
}
// represents a datasource
public class GridStorage : IGridStorage
{
public long EnsureRowsInBuf(long FirstRowIndex, long LastRowIndex)
{
return NumRows(); // pagination, dynamic load, virtualization, could happen here
}
public void FillControlWithData(long nRowIndex, int nColIndex, IGridEmbeddedControl control)
{
// for cell edition
control.SetCurSelectionAsString(GetCellDataAsString(nRowIndex, nColIndex));
}
public string GetCellDataAsString(long nRowIndex, int nColIndex)
{
// get cell data
return nRowIndex + " x " + nColIndex;
}
public int IsCellEditable(long nRowIndex, int nColIndex)
{
return 1; // 1 means yes, 0 means false
}
public long NumRows()
{
return 10000;
}
public bool SetCellDataFromControl(long nRowIndex, int nColIndex, IGridEmbeddedControl control)
{
// when a cell has changed, you're supposed to change your data here
return true;
}
public Bitmap GetCellDataAsBitmap(long nRowIndex, int nColIndex) => throw new NotImplementedException();
public void GetCellDataForButton(long nRowIndex, int nColIndex, out ButtonCellState state, out Bitmap image, out string buttonLabel) => throw new NotImplementedException();
public GridCheckBoxState GetCellDataForCheckBox(long nRowIndex, int nColIndex) => throw new NotImplementedException();
}
}
这是它的样子。你可以在一台不错的计算机上滚动而不会减速。