设为首页 收藏本站
查看: 912|回复: 0

[经验分享] Sql Server表结构及索引查询器

[复制链接]

尚未签到

发表于 2015-6-27 09:02:58 | 显示全部楼层 |阅读模式
  因经常需要处理大数量的表,因此查看表结构、数据量、以及索引情况基本上成为了常态,无奈生产环境的数据库不让我们直接访问,因此想要了解到生产环境的数据库的表结构和索引信息变得很麻烦需要经常找DBA帮忙找,而想查看具体某个表的数据量使用 select count(1) from table方法的效率实在慢的无法忍受,正所谓求人不如求己,花了点时间自己做了个查看数据库表结构和索引的小工具顺便温习了下系统表一举两得,喜欢的朋友可以拿去用用。
  工具功能很简单但胜在实用(尤其是不让开发人员用企业管理连接生产环境数据库时,简直是一大杀器),可以提高不少效率
  1.根据链接字符串列出服务器上所有的数据库以及表。
  2.查看表的记录数、字段及索引(包含覆盖索引)信息。
  默认界面如下
DSC0000.png
  根据需要修改好数据连接串,点击 链接 自动查询出数据库信息
DSC0001.png
  双击数据库加载所有的表并读取表的记录数(表名后面括号里的数字代表记录数)
DSC0002.png
  双击表名称加载表的结构和索引信息
  这里对列表字段做个简单翻译,以帮助英语不好的童鞋
 

表结构


ColumnName
ColumnType
ByteLength
CharLength
Scale
IsIdentity
IsNullable
Remark


字段名称
字段类型
字节长度
字符长度
小数位数
是否自增列
是否允许空
字段说明
  

表索引


IndexName
IndexType
IsPrimaryKey
IsUnique
IsUniqueConstraint
IndexColumns
IndexIncludeColumns


索引名称
索引类型
是否主键
是否唯一
是否唯一约束
索引包含的列
覆盖索引包含的列
  
  表结构里的Remark字段说明就是我们给列加的那个列说明,ByteLength是字段的字节长度,CharLength是字符长度,这两个主要是针对nchar,nvarchar类型的在数据库中比如定义 Name nvarchar(50),显示的字节长度是100,字符长度才是50(nvarchar一个字符占两个字节),不注意的话会很惨,曾经被这个玩意给害死(喜欢使用alt+F1 查看表结构信息,这时nvarchar(50)的字段类型会显示长度为 100)
  表索引里面IndexColumns表示索引所包含的列,IndexIncludeColumns表示覆盖索引所包含的列,比如:索引IX_Test1,IndexColumns为Name,Email,IndexIncludeColumns为Address,PostCode,覆盖索引只能建立在非聚簇索引上,主要是为了解决书签查找(RID、键查找),聚簇索引不存在书签查找所以不能创建覆盖索引,在此不再详述  



create index IX_Test1 on Users(Name,Email) include(Address,PostCode)
DSC0003.png
  恩,功能就这么简单,利用好了能在工作中省下不少事情,贴一下主要代码


DSC0004.gif DSC0005.gif SqlQuery.cs


public static class SqlQuery
{
public static List GetDatabases(string connString)
{
string sql = "select name from sys.databases where name not in ('master','model','msdb','tempdb')";
DataTable dt = DbHelperSQL.GetDataTable(connString, sql);
return dt.Rows.Cast().Select(row => row["name"].ToString()).ToList();
}
public static Dictionary GetTables(string connString, string database)
{
string sql = string.Format(@"select
objects.name+'('+ltrim(str(rows))+')' showname,
objects.name                                       
from {0}.sys.objects
inner join {0}.dbo.sysindexes on objects.object_id=sysindexes.id and sysindexes.indid0 then columns.max_length/2
when types.name='nchar' and columns.max_length>0 then columns.max_length/2
when types.name='ntext' and columns.max_length>0 then columns.max_length/2
else columns.max_length
end
) CharLength,
cast(columns.scale as int) Scale,
extended_properties.value Remark
from {0}.sys.columns
inner join {0}.sys.types on columns.system_type_id=types.system_type_id and columns.user_type_id=types.user_type_id
left join {0}.sys.extended_properties on columns.object_id=extended_properties.major_id and columns.column_id=extended_properties.minor_id
where object_id=OBJECT_ID(@tableName)
order by columns.column_id", database);
SqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, 100) { Value = database + ".dbo." + tableName };
DataTable dt = DbHelperSQL.GetDataTable(connString, sql, param);
return dt;
}
public static DataTable GetIndexs(string connString, string database, string tableName)
{
#region SQL
string sql = string.Format(@"with IndexCTE as
(
select
indexes.object_id,
indexes.index_id,
indexes.name IndexName,
indexes.type_desc IndexType,
indexes.is_primary_key IsPrimaryKey,
indexes.is_unique IsUnique,
indexes.is_unique_constraint IsUniqueConstraint
from {0}.sys.indexes
where object_id =OBJECT_ID(@tableName)
)
,IndexColumnTempCTE as
(
select
ic.object_id,
ic.index_id,
ic.column_id,
ic.index_column_id,
ic.is_included_column,
cast(c.name as nvarchar(max)) columnname,
CAST(null as nvarchar(max)) includekey
from {0}.sys.index_columns ic
inner join {0}.sys.columns c on ic.column_id=c.column_id and ic.object_id=c.object_id
where ic.index_column_id=1 and ic.object_id =OBJECT_ID(@tableName)
union all
select
ic.object_id,
ic.index_id,
ic.column_id,
ic.index_column_id,
ic.is_included_column,
case ic.is_included_column when 0 then columnname+','+c.name end,
case
when ic.is_included_column = 1 and includekey is null then c.name
when ic.is_included_column = 1 and includekey is not null then includekey+','+c.name
end
from {0}.sys.index_columns ic
inner join IndexColumnTempCTE cte on cte.index_id=ic.index_id and cte.index_column_id+1=ic.index_column_id and cte.object_id=ic.object_id
inner join {0}.sys.columns c on ic.column_id=c.column_id and ic.object_id=c.object_id
),
IndexColumnCTE as
(
select
object_id,
index_id,
max(columnname) IndexColumns,
max(includekey) IndexIncludeColumns
from IndexColumnTempCTE
group by object_id,index_id
)
select
IndexCTE.IndexName,
IndexCTE.IndexType,
IndexCTE.IsPrimaryKey,
IndexCTE.IsUnique,
IndexCTE.IsUniqueConstraint,
IndexColumnCTE.IndexColumns,
IndexColumnCTE.IndexIncludeColumns
from IndexCTE
inner join IndexColumnCTE on IndexCTE.object_id=IndexColumnCTE.object_id and IndexCTE.index_id=IndexColumnCTE.index_id
order by IndexCTE.object_id", database);
#endregion
SqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, 100) { Value = database + ".dbo." + tableName };
return DbHelperSQL.GetDataTable(connString, sql, param);
}
}

Form1.cs


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnConn_Click(object sender, EventArgs e)
{
try
{
string connString = this.txtConnString.Text;
List list = SqlQuery.GetDatabases(connString);
this.treeView1.Nodes.Clear();
this.treeView1.Nodes.AddRange(list.Select(item => new TreeNode { Text = item }).ToArray());
}
catch (Exception ex)
{
MessageBox.Show(ex.GetBaseException().Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void treeView1_DoubleClick(object sender, EventArgs e)
{
try
{
string connString = this.txtConnString.Text;
TreeNode node = this.treeView1.SelectedNode;
switch (node.Level)
{
case 0:
node.Nodes.Clear();
node.Nodes.AddRange(SqlQuery.GetTables(connString, node.Text).Select(kv => new TreeNode { Text = kv.Key, Tag = kv.Value }).ToArray());
node.Expand();
break;
case 1:
this.gridColumns.DataSource = SqlQuery.GetColumns(connString, node.Parent.Text, node.Tag.ToString());
this.gridIndexs.DataSource = SqlQuery.GetIndexs(connString, node.Parent.Text, node.Tag.ToString());
break;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.GetBaseException().Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
  
  附上源码下载:SqlQueryAnalyzer.rar
  release目录下为已经编译好的程序SqlQueryAnalyzer.exe可以直接打开使用,src目录为源码

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-80873-1-1.html 上篇帖子: SQL Server调优系列进阶篇(查询语句运行几个指标值监测) 下篇帖子: Sql Server Compact 4.0部署注意事项
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表