[转载]利用ASP.NET MVC源代码调试你的应用程序

mikel阅读(905)

[转载]利用ASP.NET MVC源代码调试你的应用程序 – 海纳百川 – 博客园.

之前写了一篇博客:利用.NET Framework4.0的源代码调试你的应用程序。 那篇文章教你如何利用.NET Framework4.0的源代码帮助你调试应用程序,其实也就是进入.NET Framework4.0源代码进行单步调试。由于项目需要,最近学起ASP.NET mvc。昨天遇到ViewData和TempData他们之间的分别这样让我纠结的问题。有园友强烈建议我去看ASP.NET MVC的源代码。所以,我想到如何在调试ASP.NET MVC程序的时候,有不明白的地方,就单步进入ASP.NET MVC的源代码,是非常好的一个办法。

所以,结合利用.NET Framework4.0的源代码调试你的应用程序这篇文章,还有看到大牛scottgu推荐的一篇博文Stepping into ASP.NET MVC Source Code。实现了如何配置VS2010来实现这样的需求。下面我将介绍一下如何去配置VS2010来实现结合ASP.NET MVC源代码进行单步调试。

1、Tools- Option – Debugging-General,按照下图修改我框起来的地方。

2、下载symbols和source

选择All modules,unless excluded,你可以下载到symbol服务器上所有更新的文件。

选择Only specified  modules,你可以只下载asp.net mvc的(也可以添加是其他模组)。

如何你只想调试asp.net mvc。选择Only specified  modules,点击它下面的specified  modules。添加一个System.Web.Mvc,如下图:

点击两次OK。随后会显示如下图,vs2010开始下载symbol。这需要登上一段时间。

等下载完成,我们下,如何单步调试TempData。

在执行Action之前,会执行PossiblyLoadTempData();

然后执行 TempData[“text”] = “aaa”;

给 TempData[“text”]赋值:

显示View之后执行

想了解更多,自己配置VS2010吧。

总结:本文教你配置VS2010,利用ASP.NET MVC源代码帮助你调试应用程序。

[转载]ASP.NET MVC2中Controller向View传递数据的三种方式

mikel阅读(1043)

[转载]ASP.NET MVC2中Controller向View传递数据的三种方式 – 海纳百川 – 博客园.

ASP.NET mvc开发中,Controller需要向View提供Model,然后View将此Model渲染成HTML。这篇文章介绍三种由Controller向View传递数据的方式,实现一个DropDownList的显示。

第一种:ViewData

ViewData是一个Dictionary。使用非常简单,看下面代码:

1 public ActionResult ViewDataWay(int id) 2 { 3 Book book =bookRepository.GetBook(id); 4 ViewData["Countries"] = new SelectList(PhoneValidator.Countries, book.Country); 5 return View(book); 6 }

在View中使用下面代码取值:

1 <div class="editor-field"> 2 <%= Html.DropDownList("Country", ViewData["Countries"] as SelectList) %> 3 <%: Html.ValidationMessageFor(model => model.Country) %> 4 </div>

上面代码使用as将它转换成SelectList。

处理POST代码如下:

1 [HttpPost] 2 public ActionResult ViewDataWay(int id, FormCollection collection) 3 { 4 Book book = bookRepository.GetBook(id); 5 UpdateModel<Book>(book); 6 bookRepository.Save(book); 7 return RedirectToAction("Details", new { id=id}); 8 }

效果:

第二种:ViewModel

使用ViewModel的方式,我们先创建一个BookViewModel,代码如下:

1 public class BookViewModel 2 { 3 public Book Book 4 { 5 get; 6 set; 7 } 8 9 public SelectList Countries 10 { 11 get; 12 set; 13 } 14 public BookViewModel(Book book) 15 { 16 Book = book; 17 Countries = new SelectList(PhoneValidator.Countries,book.Country); 18 } 19 }

在控制器的Aciton使用ViewModel存放数据的代码如下:

1 public ActionResult ViewModelWay(int id) 2 { 3 Book book = bookRepository.GetBook(id); 4 return View(new BookViewModel(book)); 5 }

在View中,这种方式比第一种方式好在:它支持智能感应。

效果和第一种方式一样。

第三种:TempData

使用TempData和使用ViewData方法是一样的。

Action代码如下:

1 public ActionResult TempDataWay(int id) 2 { 3 Book book = bookRepository.GetBook(id); 4 TempData["Countries"] = new SelectList(PhoneValidator.Countries, book.Country); 5 return View(book); 6 }

View取值的代码如下:

1 <div class="editor-field"> 2 <%= Html.DropDownList("Country", TempData["Countries"] as SelectList) %> 3 <%: Html.ValidationMessageFor(model => model.Country) %> 4 </div>

效果:第一种方式一样。

TempData和ViewData的区别

做个简单的测试看下看下TempData和ViewData的区别

1 2 public ActionResult Test1() 3 { 4 5 TempData["text"] = "1-2-3"; 6 ViewData["text"] = "1-2-3"; 7 return RedirectToAction("Test2"); 8 9 10 } 11 12 13 public ActionResult Test2() 14 { 15 16 string text1 = TempData["text"] as string; 17 string text2 = ViewData["text"] as string; 18 return View(); 19 20 }

看下面截图,发现经过Test1经过RedirectToAction跳转Test2后,ViewData的值已经被清空,而TempData没有被清空,这是它们的区别之一,我们可以用TempData在Controller之间传递数据。

关于TempData和ViewData的区别,发现网上大部分说法感觉都不对,网上有种说法:

1、TempData的数据至多只能经过一次Controller传递, 并且每个元素至多只能被访问一次

2、TempData中的元素被访问一次以后就会被删除

我试一下,发现TempData和ViewData都只会在一次请求中有效,在第二次请求的时候都失效。而TempData可以在在一次请求中的多个 Controller之间传递数据,而ViewData却不行,上图能证明。TempData也可多次访问。应该是说MVC在请求周期结束的时候有动作去 删除此类的Session,而不是访问一次就被删除。MS命名为TempData,意思应该是说TempData是个Session,但是它又和普通的 Session不同。它会在请求之后被删除,所以是临时的Data。

总结:本文简单介绍了一下在ASP.NET MVC中控制器向View传值的三种方式,还有介绍了一下TempData和ViewData的不同。如果还有其他方法,请给我留言。谢谢。

代码:http://cid-aef1e64945224a20.office.live.com/self.aspx/.Public/MvcApplication1.rar

作者:朱祁林
出处:http://zhuqil.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[转载]一步一步用C#编写三国杀(三):设计流程 - 忘却之都 - 博客园

mikel阅读(1244)

[转载][原创]一步一步用C#编写三国杀(三):设计流程 – 忘却之都 – 博客园.

前面已经说了牌堆的设计,那么现在就正式进入流程,满足我们在(一)中所说的需求。

由于在(二)中已经说了要维护扩展,因此对于之前定义的Scene,则需要定义一个所选择的扩展包,代码如下:

扩展包

private readonly IPackage[] selectedPackages;

/// <summary>
/// 初始化新的<see cref=”Scene”/>类的实例。
/// </summary>
/// <param name=”packages”>所要加载的包。</param>
public Scene(IEnumerable<IPackage> packages)
{
players[currentToken].HasToken
= true;
selectedPackages
= packages.ToArray();
}

由于玩家是轮动的,因此设定一个令牌,只有持有令牌的玩家才能行动。

private int currentToken;

那么定义一个Start方法,开始游戏循环。

首先要根据选择的扩展包生成游戏牌堆。对于游戏牌堆,由于我们之前已经定义好了牌堆基类,因此实现就比较简单了,将扩展包中的游戏牌载入并洗牌即可。

游戏牌堆

/// <summary>
/// 表示游戏牌牌堆。
/// </summary>
public sealed class GameCardHeap : CardHeap<GameCard>
{
/// <summary>
/// 初始化新的<see cref=”GameCardHeap”/>类的实例。
/// </summary>
/// <param name=”packages”>所要加载的扩展包。</param>
public GameCardHeap(IEnumerable<IPackage> packages)
{
foreach (var package in packages)
{
((List
<GameCard>) Items).AddRange(package.GameCards);
}
Items.Shuffle();
}
}

回头看我们上面的Start方法,在牌堆创建后,就进入了流程循环,还是直接来代码吧,注释都写的蛮清楚的

流程循环

/// <summary>
/// 开始游戏。
/// </summary>
public void Start()
{
Player currentPlayer;
GameCardHeap heap
= new GameCardHeap(selectedPackages); // 创建牌堆

while(true)
{
currentPlayer
= players[currentToken]; // 设置当前有令牌的玩家

// 摸牌阶段
GameCard[] newCards = heap.Pop(2, true);
currentPlayer.Draw(newCards);

// 出牌阶段
while(currentPlayer.HasPlayableCard)
{
// NOTE:为了简单,先实现只杀下家,并只使用杀、闪、桃
int nextToken = currentToken == players.Length 1 ? 0 : currentToken + 1;
currentPlayer.Play(players[nextToken], currentPlayer.FirstPlayableCard);

if (IsGameEnds())
goto label;
}

// 弃牌阶段
// NOTE:为了简单,先实现只弃从头开始的牌到当前体力值
int disCardCount = currentPlayer.HandCards.Length currentPlayer.Hp;
if (disCardCount > 0)
{
GameCard[] removeCards
= currentPlayer.HandCards.Take(disCardCount).ToArray();
currentPlayer.Discard(removeCards);
}

// 将令牌给下一个人
GiveTokenToNext();
}
label:
Console.WriteLine(
游戏结束!);
}

这里使用了一个死循环,但在游戏结束的时候使用goto语句跳出循环。所涉及到的一些方法如下:

一些辅助方法

private void GiveTokenToNext()
{
if (currentToken == players.Length 1)
currentToken
= 0;
else
currentToken
++;

players[currentToken].HasToken = true;
}

private bool IsGameEnds()
{
return players.Any(p => p.IsDead); // 如果选择到IsDead的Player,游戏结束
}

注意,流程的设计中,由于玩家是在游戏逻辑边界内的,因此采用了主动的做法来进行设计。这样对于程序来说,我只要去考虑玩家的摸牌、出牌和弃牌所引起的各种变化即可。

[转载]SQL Server性能调教系列(4)--Profiler(下)

mikel阅读(872)

[转载]SQL Server性能调教系列(4)–Profiler(下) – 我爱菊花 – 博客园.

3.分析跟踪记录

在跟踪了一段时间之后,在文件中就会保存有跟踪的数据(包括 IO,Duration,CPU,Reads,Writes,RowCounts等计数器),接下来就是把跟踪的数据加载到表并分析这些数据。可以选择在 Profile中打开并检查这些跟踪数据,会有些限制,如不能完成太多的操作,大量重复的SQL语句,没有汇总。

3.1 加载数据到表(使用函数fn_trace_gettable返回表格形式的数据,作为范例只选择分析T-SQL代码和Duration查询的运行时间)

select CAST(textdata as nvarchar(max)) as tsql_code,duration
into Workload
from sys.fn_trace_gettable('C:\test\performancetrace_20100802.trc',NULL) as TT
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }3.2 汇总相同的SQL

select tsql_code,SUM(duration) as total_duration from workload group by tsql_code
(由于我是在Production上面做的trace,考虑到系统的安全性,在此不便透露分析的SQL代码,实在很抱歉,各位朋友如有兴趣可在自己的测试环境中测试,讨论测试的结果)

问题:分组聚合后会看到逻辑上相同(参数不同)的查询会被分到不同的组,因为在筛选器中使用了不同的值。因为这些相同逻辑的SQL会使用相同的执行计划,应该聚合在一起才能准备的分析总的查询运行的时间。

3.3 问题处理方案一(大致分段截取)

通常情况下SQL语句都是Select+栏位,左边有很大一部分是相同的,根据SQL字符的长度,截取前一段来聚合。如取前50,100,150. 方法简单,容易操作,会聚合一部分数据,但是长度不太好取值,只能调整前缀的长度去测试。

select left(tsql_code,50) as t_sql,SUM(duration) as total_duration from workload group by left(tsql_code,50)

--or

select left(tsql_code,100) as t_sql,SUM(duration) as total_duration from workload group by left(tsql_code,100)

--or

select left(tsql_code,150) as t_sql,SUM(duration) as total_duration from workload group by left(tsql_code,150)

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

3.4 问题处理方案二(复杂,精确,逻辑上相同的SQL,参数用通配符替代),这个方法是T-SQL查询技术内幕中介绍的方法,如果需要更加详细的说明,请阅读这本书,你会得到更多的启发。

(1) 模式化查询,它对于相同模式的查询是一样的。

  • T-SQL函数实现

建立函数:

CREATE FUNCTION [dbo].[fn_SQLSigTSQL] 
  (@p1 NTEXT, @parselength INT = 4000)
RETURNS NVARCHAR(4000)

-- This function will replace the parameters with '#'
-- This function is provided "AS IS" with no warranties,
-- and confers no rights. 
-- Use of included script samples are subject to the terms specified at
-- http://www.microsoft.com/info/cpyright.htm
-- 
-- Strips query strings
AS
BEGIN 
  DECLARE @pos AS INT;
  DECLARE @mode AS CHAR(10);
  DECLARE @maxlength AS INT;
  DECLARE @p2 AS NCHAR(4000);
  DECLARE @currchar AS CHAR(1), @nextchar AS CHAR(1);
  DECLARE @p2len AS INT;

  SET @maxlength = LEN(RTRIM(SUBSTRING(@p1,1,4000)));
  SET @maxlength = CASE WHEN @maxlength > @parselength 
                     THEN @parselength ELSE @maxlength END;
  SET @pos = 1;
  SET @p2 = '';
  SET @p2len = 0;
  SET @currchar = '';
  set @nextchar = '';
  SET @mode = 'command';

  WHILE (@pos <= @maxlength)
  BEGIN
    SET @currchar = SUBSTRING(@p1,@pos,1);
    SET @nextchar = SUBSTRING(@p1,@pos+1,1);
    IF @mode = 'command'
    BEGIN
      SET @p2 = LEFT(@p2,@p2len) + @currchar;
      SET @p2len = @p2len + 1 ;
      IF @currchar IN (',','(',' ','=','<','>','!')
        AND @nextchar BETWEEN '0' AND '9'
      BEGIN
        SET @mode = 'number';
        SET @p2 = LEFT(@p2,@p2len) + '#';
        SET @p2len = @p2len + 1;
      END 
      IF @currchar = ''''
      BEGIN
        SET @mode = 'literal';
        SET @p2 = LEFT(@p2,@p2len) + '#''';
        SET @p2len = @p2len + 2;
      END
    END
    ELSE IF @mode = 'number' AND @nextchar IN (',',')',' ','=','<','>','!')
      SET @mode= 'command';
    ELSE IF @mode = 'literal' AND @currchar = ''''
      SET @mode= 'command';

    SET @pos = @pos + 1;
  END
  RETURN @p2;
END

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

该函数参数为一个查询字符串和要分析的代码的长度,但会输入查询的签名,并用井号(#)替换所有的参数。测试结果如下:

select dbo.fn_SQLSigTSQL('select * from Sales.SalesOrderHeader where SalesOrderID=''43659'' and Status=''5'' ',500)

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }image

  • CLR实现

CLR在处理迭代/过程逻辑和字符串处理时比T-SQL效率高,下面介绍用CLR实现模式化查询。

a. 建立C#版的Classs Libary,函数如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Text.RegularExpressions;
public partial class SQLSignature
{
    // fn_SQLSigCLR
    [SqlFunction(IsDeterministic = true, DataAccess = DataAccessKind.None)]
    public static SqlString fn_SQLSigCLR(SqlString querystring)
    {
        return (SqlString)Regex.Replace(
            querystring.Value,
            @"([\s,(=<>!](?![^\]]+[\]]))(?:(?:(?:(?#    expression coming
             )(?:([N])?(')(?:[^']|'')*('))(?#           character
             )|(?:0x[\da-fA-F]*)(?#                     binary
             )|(?:[-+]?(?:(?:[\d]*\.[\d]*|[\d]+)(?#     precise number
             )(?:[eE]?[\d]*)))(?#                       imprecise number
             )|(?:[~]?[-+]?(?:[\d]+))(?#                integer
             ))(?:[\s]?[\+\-\*\/\%\&\|\^][\s]?)?)+(?#   operators
             ))",
            @"$1$2$3#$4");
    }
    // fn_RegexReplace - for generic use of RegEx-based replace
    [SqlFunction(IsDeterministic = true, DataAccess = DataAccessKind.None)]
    public static SqlString fn_RegexReplace(
        SqlString input, SqlString pattern, SqlString replacement)
    {
        return (SqlString)Regex.Replace(
            input.Value, pattern.Value, replacement.Value);
    }
}

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

b. 加载.dll中间语言代码到DB

USE master;
CREATE ASSEMBLY SQLSignature
FROM 'C:\SQLSignature\SQLSignature\bin\Debug\SQLSignature.dll';

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

c. 注册函数fn_SQLSigCLR和fn_RegexReplace

CREATE FUNCTION dbo.fn_SQLSigCLR(@querystring AS NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
WITH RETURNS NULL ON NULL INPUT 
EXTERNAL NAME SQLSignature.SQLSignature.fn_SQLSigCLR;
GO

CREATE FUNCTION dbo.fn_RegexReplace(
  @input       AS NVARCHAR(MAX),
  @pattern     AS NVARCHAR(MAX),
  @replacement AS NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
WITH RETURNS NULL ON NULL INPUT 
EXTERNAL NAME SQLSignature.SQLSignature.fn_RegexReplace;
GO

d. 注册完成之后,用下面代码测试:

SELECT
  dbo.fn_SQLSigCLR(tsql_code) AS sig_sql,
  duration
FROM dbo.Workload;

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

结果的SQL全被模式化,井号(#)替代所有的参数。

(2) 以用上面建立的函数,模式化追踪的T-SQL语句,并分类汇总。

a. 以用查询签名,为每个字符串生成整数的校验和(CheckSum),方便以后的汇总计算,提高效率:

ALTER TABLE dbo.Workload ADD cs INT NOT NULL DEFAULT (0);
GO
UPDATE dbo.Workload
  SET cs = CHECKSUM(dbo.fn_SQLSigCLR(tsql_code));

CREATE CLUSTERED INDEX idx_cl_cs ON dbo.Workload(cs);

b. 用每个签名的检验和计算运行时间填充临时表#AggQueries,包括运行时间的百分比,以及运行时间降序的行号。

IF OBJECT_ID('tempdb..#AggQueries') IS NOT NULL
  DROP TABLE #AggQueries;
GO

SELECT cs, SUM(duration) AS total_duration,
  100. * SUM(duration) / SUM(SUM(duration)) OVER() AS pct,
  ROW_NUMBER() OVER(ORDER BY SUM(duration) DESC) AS rn
INTO #AggQueries
FROM dbo.Workload
GROUP BY cs;

CREATE CLUSTERED INDEX idx_cl_cs ON #AggQueries(cs);

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

查询聚合之后临时表的内容,数据量会大大的减少,包含签名,总的运行时间,运行时间占总运行时间的半分比,排序序号。

c.筛选并匹配,使用APPLY运算符得到查询模式和一个示例查询。

WITH RunningTotals AS
(
  SELECT AQ1.cs,
    CAST(AQ1.total_duration / 1000.
      AS DECIMAL(12, 2)) AS total_s, 
    CAST(SUM(AQ2.total_duration) / 1000.
      AS DECIMAL(12, 2)) AS running_total_s, 
    CAST(AQ1.pct AS DECIMAL(12, 2)) AS pct, 
    CAST(SUM(AQ2.pct) AS DECIMAL(12, 2)) AS run_pct, 
    AQ1.rn
  FROM #AggQueries AS AQ1
    JOIN #AggQueries AS AQ2
      ON AQ2.rn <= AQ1.rn
  GROUP BY AQ1.cs, AQ1.total_duration, AQ1.pct, AQ1.rn
  HAVING SUM(AQ2.pct) - AQ1.pct <= 90 -- percentage threshold
)
SELECT RT.rn, RT.pct, S.sig, S.tsql_code AS sample_query
FROM RunningTotals AS RT
  CROSS APPLY
    (SELECT TOP(1) tsql_code, dbo.fn_SQLSigCLR(tsql_code) AS sig
     FROM dbo.Workload AS W
     WHERE W.cs = RT.cs) AS S
ORDER BY RT.rn;

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }4. 有了查询模式,示例查询,和占用时间的百分比例和排序。然后就可以着手优化。也可以通过类似的方式,找到造成大量结果集,大多数的I/O问题的查询模式。

四:总结

Perfiler是一个很好用的工具来追踪系统的性能和工作的负荷,从而准确的找到值得优化的SQL,提高效率,大大减少工作量。

参考:Microsoft SQL Server 2005技术内幕:T-SQL查询

>>>性能调校系列入口地址

[转载]SQL Server性能调教系列(4)--Profiler(上)

mikel阅读(1021)

[转载]SQL Server性能调教系列(4)–Profiler(上) – 我爱菊花 – 博客园.

一:简介

在处理性能问题是,DBA倾向于关注系统技术层面,如资源队列,资源利用率,系统loading等。而用户只把性能问题认为是等待,他们从业务逻辑 层面发出一个请求,等待返回结果,后台数据库就需要去响应这个请求。从用户角度来看,一般认为等待三秒才返回就属于性能问题(特殊的系统除外:比如需要大 量的数据操作),他们并不关心系统的数据层,比如有多少个命令在等待处理,CPU利用率,RAM使用率等。在遇到这些问题之后,我们需要找到这个问题,请 着手优化,找到合理的解决方案。

注:硬件方面的问题请参照系列(2)

SQL Server性能调教系列(2)–Server Performance Monitor(Perfmon)

二:理论

要做优化,首先要找出需要优化的部分(如找到效率低的SQL或SP等),引用SQL技术内幕中介绍的优化步骤:

1.分析实例级的等待

2.联系等待的队列

3.确定方案

4.细化到数据库/文件级

5.细化到进程级

6.优化索引/查询

三:方法

本章主要介绍Profiler工具来跟踪性能工作负荷。

1. Profiler简介

通过SQL Server—>Tools—>SQL Server Profiler启动

捕获

General页:跟踪的记录有两种保存方式:保存到文件和保存到表。通常选择保存到文件,因为保存到表会增加较多的额外系统开销。

Events Selection页:能够选择跟踪的事件。更多的跟踪事件请参考MSDN。

1

注:

  • 不要使用GUI跟踪,应该使用T-SQL。因为使用GUI会有两个跟踪,一个把跟踪信息写入目标文件,一个把跟踪信息写入运行的GUI,会增加系统的额外开销。
  • 不要把跟踪直接写入到表,这样会严重影响性能,把文件写到磁盘是最快的方案。
  • 跟踪会产生大量和额外的IO操作。不要把跟踪文件放到包含数据库文件(如数据,日志和tempdb)的磁盘上。
  • 选择事件类的数据列,只跟踪需要的信息。
  • 使用跟踪筛选需要的事件。

2.启动跟踪

2.1  可以先在GUI中设置需要跟踪的事件类,然后在导出脚本(File—>Export–>Script Trace Definition),通常筛选Duration数列大于某些值(比如3000毫秒)的事件来跟踪运行得比较慢的进程。

如:导出的脚本如下,这里把trace的脚本整理为一个存储过程,以方便执行.

CREATE PROC [dbo].[sp_perfworkload_trace_start]
  @dbid      AS INT,
  @tracefile AS NVARCHAR(254),
  @traceid   AS INT OUTPUT
AS
-- Create a Queue
DECLARE @rc          AS INT;
DECLARE @maxfilesize AS BIGINT;

SET @maxfilesize = 100;

EXEC @rc = sp_trace_create @traceid OUTPUT, 0, @tracefile, @maxfilesize, NULL
IF (@rc != 0) GOTO error;

-- Client side File and Table cannot be scripted

-- Set the events
DECLARE @on AS BIT;
SET @on = 1;
EXEC sp_trace_setevent @traceid, 10, 15, @on;
EXEC sp_trace_setevent @traceid, 10, 8, @on;
EXEC sp_trace_setevent @traceid, 10, 16, @on;
EXEC sp_trace_setevent @traceid, 10, 48, @on;
EXEC sp_trace_setevent @traceid, 10, 1, @on;
EXEC sp_trace_setevent @traceid, 10, 17, @on;
EXEC sp_trace_setevent @traceid, 10, 10, @on;
EXEC sp_trace_setevent @traceid, 10, 18, @on;
EXEC sp_trace_setevent @traceid, 10, 11, @on;
EXEC sp_trace_setevent @traceid, 10, 12, @on;
EXEC sp_trace_setevent @traceid, 10, 13, @on;
EXEC sp_trace_setevent @traceid, 10, 14, @on;
EXEC sp_trace_setevent @traceid, 45, 8, @on;
EXEC sp_trace_setevent @traceid, 45, 16, @on;
EXEC sp_trace_setevent @traceid, 45, 48, @on;
EXEC sp_trace_setevent @traceid, 45, 1, @on;
EXEC sp_trace_setevent @traceid, 45, 17, @on;
EXEC sp_trace_setevent @traceid, 45, 10, @on;
EXEC sp_trace_setevent @traceid, 45, 18, @on;
EXEC sp_trace_setevent @traceid, 45, 11, @on;
EXEC sp_trace_setevent @traceid, 45, 12, @on;
EXEC sp_trace_setevent @traceid, 45, 13, @on;
EXEC sp_trace_setevent @traceid, 45, 14, @on;
EXEC sp_trace_setevent @traceid, 45, 15, @on;
EXEC sp_trace_setevent @traceid, 41, 15, @on;
EXEC sp_trace_setevent @traceid, 41, 8, @on;
EXEC sp_trace_setevent @traceid, 41, 16, @on;
EXEC sp_trace_setevent @traceid, 41, 48, @on;
EXEC sp_trace_setevent @traceid, 41, 1, @on;
EXEC sp_trace_setevent @traceid, 41, 17, @on;
EXEC sp_trace_setevent @traceid, 41, 10, @on;
EXEC sp_trace_setevent @traceid, 41, 18, @on;
EXEC sp_trace_setevent @traceid, 41, 11, @on;
EXEC sp_trace_setevent @traceid, 41, 12, @on;
EXEC sp_trace_setevent @traceid, 41, 13, @on;
EXEC sp_trace_setevent @traceid, 41, 14, @on;

-- Set the Filters
DECLARE @intfilter AS INT;
DECLARE @bigintfilter AS BIGINT;
-- Application name filter
EXEC sp_trace_setfilter @traceid, 10, 0, 7, N'SQL Server Profiler%';
-- Database ID filter
EXEC sp_trace_setfilter @traceid, 3, 0, 0, @dbid;

-- Set the trace status to start
EXEC sp_trace_setstatus @traceid, 1;

-- Print trace id and file name for future references
PRINT 'Trce ID: ' + CAST(@traceid AS VARCHAR(10))
  + ', Trace File: ''' + @tracefile + '''';

GOTO finish;

error:
PRINT 'Error Code: ' + CAST(@rc AS VARCHAR(10));

finish:
<!– .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } –>

2.2 用以下T-SQL代码启动跟踪:

declare @dbid int,@traceid int;
set @dbid=DB_ID()---可以为默认的DB,或者DB_ID('Your_dbname')
EXEC sp_perfworkload_trace_start @dbid,'C:\test\performancetrace_20100802.trc',@traceid output

<!– .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } –> <!– .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } –> <!– .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } –>

执行之后会显示出traceid,请记住这个traceid,会用它来停止和关闭追踪。

Trce ID: 2, Trace File: ‘C:\test\performancetrace_20100802.trc’

2.3 停止和关闭追踪(sp_trace_setstatus,如果traceid是2,则停止和关闭的代码如下):

EXEC sp_trace_setstatus 2,0 
EXEC sp_trace_setstatus 2,2

<!– .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } –>2.4

如果忘记traceid,可以在查询试图sys.traces找到。

捕获

接下篇:

SQL Server性能调教系列(4)–Profiler(下)

>>>性能调校系列入口地址

[转载].NET ADOX创建Access数据库

mikel阅读(1077)

[转载].NET ADOX创建Access数据库 – 编程随笔 – 博客园.

前几天做一个软件,其中一个功能是让用户能创建数据库,这个地方原来没有接触过,一般都是先创建好,再连接查询等就OK了,但是用.net创建还是第一次遇到,呵呵,才疏学浅,其中的方法留在这里供日后参考。

首先是创建一个数据库,先引用COM组件中的Microsoft ADO Ext. 2.8 for DDL,添加完成后 项目中的引用会增加一个ADOX的引用,好了,这样就可以创建一个空的Access数据库了:

string _DataSource = string.Format(@”Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Jet OLEDB:Engine Type=5″, _Dir);
ADOX.Catalog _cata = new Catalog();

_cata.Create(_DataSource);

也就这三行就行了。

当然,不能只创建出一个空的库,里面要有表,字段,等。这次要用的Microsoft ActiveX Data Objects 2.8 Library,先创建连接

ADODB.Connection _Con = new ADODB.Connection();

_Con.Open(_DataSource, null, null,-1);

_cata.ActiveConnection = _Con;

建立好连接后,就可已建立表了

ADOX.Table _NewTable = new ADOX.Table();
_NewTable.Name = “Spiderbase”;

然后字段

ADOX.Column _Column = new ADOX.Column();
_Column.ParentCatalog = _cata;
_Column.Name = “ID”;
_Column.Type = DataTypeEnum.adInteger;
_Column.DefinedSize = 9;
_Column.Properties[“AutoIncrement”].Value = true; //这里首先建立ID列

_NewTable.Columns.Append(_Column, DataTypeEnum.adInteger, 9);
_NewTable.Keys.Append(“IDKey”, KeyTypeEnum.adKeyPrimary, _Column, null, null);//设置主键

_NewTable.Columns.Append(“Statement”, DataTypeEnum.adVarWChar, 200);
_NewTable.Columns[“Statement”].Attributes = ColumnAttributesEnum.adColNullable;
_NewTable.Columns.Append(“标题”, DataTypeEnum.adVarWChar, 200);
_NewTable.Columns[“标题”].Attributes = ColumnAttributesEnum.adColNullable;

其中的.Attributes属性中的ColumnAttributesEnum是设置约束的(NOT NULL);

好了 ,就这样,一个表就建立好了

最后 _cata.Tables.Append(_NewTable);就行了

[转载]Web打印利器之-PbDataWindow

mikel阅读(1300)

[转载]Web打印利器之-PbDataWindow – Vincent.Q – 博客园.

业务场景

前段时间公司要把PB的东东搞到ASP.NET项目里,并实现打印.考虑过使用水晶报表,这样PB的DataWindow(数据窗口)就用不上了, 这个很心痛,而且水晶报表相当于是个鸡肋.(书中暗表,PB的DataWindow相当相当的强大,不用确实可惜).经过多方打探和印证,PB的 DataWindow有个active的web控件,叫active datawindow.其实sybase本身推出了datawindow.net,但个人感觉,使用起来没有active datawindow好用.

active datawindow的强大之外在于

l 可以以字符串方式加载数据

l ASP.NET所涉及的样式表,js代码一律不需要,我们只需要在后台将数据加载至dataset或datatable对象里即可,调用一个转为字符串的方法,直接加载即可

l PB中可以用Create方式在DataWindow中创建一个对象,同样的语法,直接可以在active datawindow调用.这样就最大程度的解决了PB和Net间共用问题.

好了,废话不多说了.先看一下整体效果图,如图-1所示.本篇贴子就是详细讲解一下如何使用这个控件实现web打印.

clip_image002

图-1

怎么样,效果还可以吧!展示区部分,使用的就是active datawindow控件.如果使用拼接html字符串的方式,可能要拼上一段时间吧,而且html的样式也可拼接进去.至少对于我来说,我会疯掉.现在web开发流行这样一句话:行为和结构分开!

实现环境

首先,要装个pb11.5,原因是需要其中的dll和cab文件,只要有这些dll和cab包之外,再加上pb必备的dll文件,也可以不装pb11.5的(所有的dll和cab文件,均可以下载).文件列表如下所示,如图-2和图-3所示

clip_image003

图-2

clip_image004

图-3

若已安装pb11.5的

cab文件在\Sybase\Shared\PowerBuilder文件夹

dll文件在\Sybase\PowerBuilder 11.5\DotNET\bin文件夹.还有一部分dll文件是pb必备的,在系统盘的/window/system32/文件夹里可以找到,pb开头的

实现步骤

下面我们通过一个完整的实例来展现它的强大

第1步,搭建环境,新建一个web项目解决方案,将我们之前安装好的cab和dll文件放进来,整体布局如图-4所示

clip_image005

图-4

在此说明下

App_Code是针对这个控件封装的一些类

Cab是控件安装包

Pbl是数据窗口展示部分,一个页面的样式,布局,非数据部分都在这里存储

Public下面的js文件,也是针对这个控件封装的js前端类

这里要注意一下,由于此控件加载数据是通过ajax方法从后端取数据加载的,因此前后端交互所产生的数据量会比较大,需要在web.config加上如下代码,如图-5所示

clip_image006

图-5

其次,我们需要布局一个页面,比如样式,文字大小和颜色等,这里我使用的是PB11.5,目前没有什么好工具可以替代PB来画数据窗口,如图-6所示,我们画好了一个页面

clip_image008

图-6

里面对于文字的大小,字体,颜色等都可以调整.而且还可以把数据窗口导出至字符串文件,如图-7所示

clip_image010

图-7

保存成字符串的文件后,好处多多啊!

第2步,在页面中引用此控件,如图-8所示

clip_image012

图-8

引入之后,所有准备工作都以完成,接下来就直接编写代码了

第3步,编程实现数据加载,采用的是ajax从后台取数据,在前台加载,我们先看看后台代码,如图-9所示

clip_image013

图-9

我们说下代码的思路

1. 首先,创建一个datastore对象,相当于net里的dataset/datatable,即数据集,创建它时,要指定它是所属哪个数据窗口(相当于数据源,SQL语句是啥)

2. 其次,将要加载至此控件中的数据加载至dataset或datatable对象中,然后通过ds_print.Retrieve(table_data) 即可实现绑定,看就这一句话,就实现了数据的加载,加载好以后,通过ajax方法传至前台页面,前台页面接收到值以后,按图-10所示代码即可实现加载

clip_image014

图-10

至此,加载数据过程结束,让我们看看最终效果图,如图-11所示

clip_image016

图-11

提供的示例项目中有详细代码,在此不再赘述.

开发结论

1. 整个开发过程中,最为复杂的环节属于画页面的过程,加载数据只需加载至dataset/datatable对象中即可

2. 动态实现控件赋值,如图-12所示.同时我们还可以动态的创建控件,删除控件,控件包括图片,计算域均可

clip_image017

图-12

3. 较为复杂的报表,比如主明细,有表头和表尾,套打之类的,都没有问题.

结论

在bs软件中实现cs方式的打印,实在是bs软件打印功能的利器,在此强烈推荐!

FAQ

1. 问:执行打印事件时没有响应?

答:需要指定一个打印机名称,在前台代码中指定即可,如图-13

clip_image018

图-13

2. 问:所有控件都可以动态创建吗?

答:可以,请参考PbDwModelWebUI类方法

3. 问:有表头,表体和表尾的报表如何处理?

答:制作数据窗口的时候,制作为复合式数据窗口,分别对这个数据窗口中的子数据窗口加载数据即可,详细代码请参考PbDwModelWebUI类

4. 问:数据窗口中栏目类型是下拉菜单如何加载其数据源?

答:将下拉菜单的数据源看成是datatable即可,也相当于子数据窗口,详细代码请参考PbDwModelWebUI类

5. 问:关于此控件的帮助文档在哪可以找到?

答:PB11.5编程环境中即可找到,如图-14所示.browser页面内,选ole页面即可

clip_image019

图-14

6. 问:提示控件安装失败或者没有提示安装

答:在ie选项-高级里,关于active控件的选项,置为提示或启用,如果仍然不可以,再在ie选项->安全->自定义级别里,将active控件的选项,置为提示或启用即可

最后,祝大家使用此控件愉快,同时,本人免费提供该控件技术支持!

源码WebPbDataWindow

[转载]Oracle学习笔记(3)

mikel阅读(1136)

[转载]Oracle学习笔记(3) – Soul Not Found… – 博客园.

这一篇是总结Oracle的数据库管理(database),重点是其物理存储部分。图在下面,点击放大。

一些SQL命令:

手工切换重做日志文件组:

SQL> alter system switch logfile;

添加联机重做日志文件组:

SQL> alter database add logfile group 4 ('/oradata/log4a.log','/oradata/log4b.log') size 10M;
/*其中的10M是指每个日志成员文件的大小*/

添加联机重做日志文件组成员:

SQL> alter database add logfile member '/oradata/log4c.log' to group 4, '/oradata/log3c.log' to group 3;

删除联机重做日志文件组(当前组不能删除,至少保留两组):

SQL> alter database drop logfile group 4;

删除联机重做日志文件组成员(只有一个成员时不能删除):

SQL> alter database drop logfile member '/oradata/log4a.log';

清除日志文件内容:

SQL> alter database clear logfile '/oradata/log3c.log';

关于三大核心文件的几点注意事项:

1、控制文件最多可以有8个,多个控制文件最好放在不同的物理磁盘上,有一个出错时可以从其他文件恢复。

2、重做日志文件组是按顺序写、循环写。至少需要两个组,可以有多个组,每个组可以有多个成员,每个成员文件最好也放在不同的物理磁盘上。当归档模式下日志文件占用空间过大时,可以删除部分组来节省空间,但记住从控制文件中删除之后还必须删除物理文件才能腾出空间。

3、不可以删除当前正在使用的重做日志文件组,所以要删除时可手动切换(switch)当前日志文件组后再删除。

4、不可以删除重做日志文件组的最后一个成员,若要删除,可直接删除该组。

5、必须要保留两个重做日志文件组支持正常运行,如果要想删除其中一组是不可能的,但可以清除(clear)其中的数据。

一句话观点:“成功启动Oracle数据库的唯一条件是三大核心文件(控制文件、数据文件、日志文件)的检查点一致。”

[转载]Oracle学习笔记(2)

mikel阅读(961)

[转载]Oracle学习笔记(2) – Soul Not Found… – 博客园.

今天的内容有点多,分成了两篇,这里是比较简单的第一篇,是总结安装、启动和关闭的过程,先上图,点击放大。

一些SQL命令和语句:

建立数据库时加cache子句可以把表同时建立在内存中,读取时优先读取该表:

SQL> create table emp1 cache as select * from emp;

查看内存中的表:

SQL> select table_name, cache from user_tables;

查询参数信息:

/* show parameter 参数类型;*/
SQL> show parameter process;
/* select * from v$parameter where name like '%参数类型%' */
SQL> select * from v$parameter where name like '%session%';

生成pfile和spfile:

/*从spfile生成pfile*/
SQL> create pfile from spfile;
/*从pfile生成spfile*/
SQL> create spfile from pfile;

按步骤启动数据库:

SQL> startup nomount; /*仅启动例程*/
SQL> alter database mount; /*再加载数据库*/
SQL> alter database open [read only] /*再打开数据库(只读模式)*/

启动时指定参数文件:

SQL> startup pfile='/database/initSID2.ora';

以受限方式启动:

SQL> startup restrict;

把数据库设置为受限模式:

SQL> alter system enable restricted;

修改参数文件内容:

SQL> alter system set control_files='/control01.ctl' scope=spfile;

关于Oracle的故障查找:

1、发生故障时的第一步要做的是备份当前的数据,这叫保留事故现场,以免处理故障失败时无法再现初始故障。

2、分步骤启动,确定故障所在:如果第1步失败,则要先检查共享内存、参数文件配置等;如果在第2步失败,则说明极有可能是控制文件出错,要先检查 警告文件中的警告信息,恢复控制文件再说;如果在第3步失败,则要检查数据文件和日志文件是否完整可用,也可根据警告文件中的警告信息来排查故障。

3、确认三大核心文件(控制文件、数据文件、日志文件)的检查点是否一致,这是数据库能启动的唯一标志。

一句话观点:“Oracle中的绝大部分故障,都可以从启动的过程中分析出故障的原因并加以解决。”

[转载]Oracle学习笔记(1)

mikel阅读(1028)

[转载]Oracle学习笔记(1) – Soul Not Found… – 博客园.

这是我的Oracle学习笔记系列的第一篇,主要总结了Oracle的体系结构,要学好Oracle,就要先了解Oracle的运行机制和原理。把今天学习的内容整理了一个图,备忘,点击可放大。

另外,还有几个语句(SQL*plus):

SYS用户登录

SQL> / as sysdba;

解锁scott用户

SQL> alter user scott identified by tiger account unlock;

切换到scott用户

SQL> conn scott/tiger;

Null值参与列计算

SQL> select ename, sal, comm, (sal+nvl(comm,0)) as salary from emp;

SQL*plus中用变量查询

SQL> variable va number;
SQL> declare :va:=7788;
SQL> select empno,ename,sal from emp where empno = :va;

看内存中包含”select * from”的SQL语句

SQL> select sql_text from v$sqlarea where sql_text like '%select * from%';

看内存(SGA)资源情况

SQL> select * from v$sgastat;

刷内存共享池

SQL> alter system flush shared_pool;

强制重启实例

SQL> startup force;

在会话中修改日期格式

SQL> alter session set nls_date_format='yyyy-mm-dd';

如果要永久修改,windows下可在注册表中建立一个名为 nls_date_format 的DWORD值,UNIX/LINUX直接配置环境变量。

关于共享池和SQL语句同性能的关系:

由于共享池中缓存最近SQL语句的特性,所以在构建SQL语句时要特别注意,大小写不同、空格、顺序不同都会被Oracle认为是不同的SQL语 句,只有完全一样的SQL语句才会从共享池中保存的SQL语句中重复使用,而由于编写SQL语句的不规范将会产生性能问题,所以要做到:

1、尽量规范SQL语句,用统一的格式,大小写、顺序、空格、缩进、变量名格式都有相应的规范并严格遵守;

2、在大量的同一格式的SQL语句查询时(比如只有where条件的值不同),应尽量使用变量,否则共享池将被大量的垃圾查询占满而使常用的SQL不被缓存,影响效率;

3、PL/SQL或者是复杂的数据查询,可以写存储过程,用带进参数的方式保证共享池中的SQL语句一致;

4、适当调整 shared_pool_size 的大小。

一句话观点:“备份和恢复数据库应该用物理备份的方式而不要用导出和导入功能,除非你的数据库数据量很少,而且都不太重要。”

参考:

Oracle的SQL语法,可以查看豆丁的这个文档:《Oracle SQL语法大全》