SqlServer性能優化 即席查詢(十三)


 執行計划,查詢類別:

  1.即席查詢     2.預定義查詢

select c.EnglishProductCategoryName,p.EnglishProductName,p.Color,p.Size
from Product as p inner join ProductCategory as c on p.ProductSubcategoryKey=
c.ProductCategoryKey where p.Size>'1'

--查詢執行計划是否被緩存 select c.usecounts,c.size_in_bytes,c.objtype,t.text from sys.dm_exec_cached_plans as c cross apply sys.dm_exec_sql_text(c.plan_handle) as t dbcc freeproccache--清空執行計划
--沒有join 的形式會生成簡單參數化 select EnglishProductName,Color,Size from Product where size>'1'--簡單參數化

select EnglishProductName,Color,Size from Product where size>'2'--簡單參數化

 

 

select c.EnglishProductCategoryName,p.EnglishProductName,p.Color,p.Size
from Product as p inner join ProductCategory as c on p.aProductSubcategoryKey=
c.ProductCategoryKey where p.Size>'2'

語句一樣時即席查詢才會重用執行計划。

 

優化:打開開關

exec sp_configure 'show advanced options',1
reconfigure with override

 為ad hoc的查詢優化:

exec sp_configure 'Optimize for ad hoc workloads',1
reconfigure with override

 

 

--使用參數化
alter database HRDB
set Parameterization forced

  set Parameterization forced 強制參數化(like無法識別 ) 

select c.EnglishProductCategoryName,p.EnglishProductName,p.Color,p.Size
from Product as p inner join ProductCategory as c on p.ProductSubcategoryKey=
c.ProductCategoryKey where p.Size>'2'

select c.EnglishProductCategoryName,p.EnglishProductName,p.Color,p.Size
from Product as p inner join ProductCategory as c on p.ProductSubcategoryKey=
c.ProductCategoryKey where p.Size like '2%'

 

 

預定義查詢:

預定義查詢--參數化執行計划:

     存儲過程:

           1.創建時延時檢查

           2.第一次執行時編譯並生成執行計划

           3.減少網絡傳輸量

           4.封裝變化點

           5.增強安全性,隔離訪問控制

創建存儲過程:

create procedure p_querycp @size varchar(500)
as
select c.EnglishProductCategoryName,p.EnglishProductName,p.Color,p.size
from Product as p inner join ProductCategory as c on p.ProductSubcategoryKey=c.ProductCategoryKey
where p.Size>@size

 做跟蹤(以前有對應得截圖):

執行存儲過程:

create procedure p_querycp @size varchar(500)
as
select c.EnglishProductCategoryName,p.EnglishProductName,p.Color,p.size
from Product as p inner join ProductCategory as c on p.ProductSubcategoryKey=c.ProductCategoryKey
where p.Size>@size

--清空執行計划
dbcc freeproccache
--執行
exec p_querycp '1'

 執行重復的語句:

dbcc freeproccache

exec p_querycp @size='1'

exec p_querycp @size='2'

 查看緩存計划:

select c.usecounts,c.size_in_bytes,c.objtype,t.text from sys.dm_exec_cached_plans as c
cross apply sys.dm_exec_sql_text(c.plan_handle) as t

 

 

預定義查詢---參數化執行計划:

SP_ExecuteSql

      避免了自己維護存儲過程管理成本

      可重用執行計划

      Unicode字符串作為參數值與類型

      大小寫敏感

 

把存儲過程定義成傳遞參數的:

declare @sqltext nvarchar(500)
set @sqltext=N'
select c.EnglishProductCategoryName,p.EnglishProductName,p.Color,p.size
from Product as p inner join ProductCategory as c on p.ProductSubcategoryKey=c.ProductCategoryKey
where p.Size>@size
'
declare @params	nvarchar(500)
set @params=N'@size varchar(500)'
 exec sp_executesql @sqltext,@params,@size='1'

 

 

把size 的大小換成  2

 

 

 在.net中調用:(兩種寫法)

        public object getCp(string size)
        {
            HRUser dbcontext = new HRUser();
            var cps = from p in dbcontext.Product
                      join c in dbcontext.ProductCategory
                      on p.ProductSubcategoryKey equals c.ProductCategoryKey
                      where p.Size == size
                      //返回匿名對象
                      select new
                      {
                          CName = c.EnglishProductCategoryName,
                          PName = p.EnglishProductName,
                          Color = p.Color,
                          Size = p.Size
                      };
            return cps.ToList();
        }
public object getcp(string size) { HRUser dbcontext = new HRUser(); var cps = dbcontext.Product.Join(dbcontext.ProductCategory, a => a.ProductSubcategoryKey, ar => ar.ProductCategoryKey, (a, ar) => new { CName = ar.EnglishProductCategoryName, PName = a.EnglishProductName, Color = a.Color, Size = a.Size }).Where(p => p.Size == size); return cps.ToList(); }

 頁面:

  <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="顯示產品" />
    <asp:GridView ID="GridView1" runat="server">
    </asp:GridView>

 點擊后的事件:

  protected void Button2_Click(object sender, EventArgs e)
        {
            Product p = new Product();
            var cps = p.getCp(TextBox1.Text.Trim());
            GridView1.DataSource = cps;
            GridView1.DataBind();
        }

 

 

 

--動態構建語句(執行帶參數的方法)
 declare @size varchar(500)
set @size='2'
execute('select c.EnglishProductCategoryName,p.EnglishProductName,p.Color,p.size
from Product as p inner join ProductCategory as c on p.ProductSubcategoryKey=c.ProductCategoryKey
where p.Size>'+''''+@size+'''')
	

 

dbcc freeproccache

--執行計划 緩存
select c.usecounts,c.size_in_bytes,c.objtype,t.text from sys.dm_exec_cached_plans as c
cross apply sys.dm_exec_sql_text(c.plan_handle) as t

形成兩個緩存計划:

 

創建存儲過程:

create  procedure p_querye @vacationhours  int
as
select e.LoginID,e.JobTitle from EmployeeOp as e where VacationHours>@vacationhours 
exec p_querye 2--實際執行計划 表掃描

exec p_querye 99--實際執行計划 表掃描 應用用索引更好

 

 

--重新編譯的執行計划
exec p_querycp 99 with recompile 

 

 

手工的指定執行幾乎:

--手工的指定執行計划
exec  sp_create_plan_guide @name='執行任務計划指南之EmployeeOp Vacation',
--轉成Unicode編碼格式
@stmt=N'select e.LoginID,e.JobTitle from EmployeeOp as e where VacationHours>@vacationhours',
@type=N'Object',
--執行計划的名字
@module_or_batch ='p_querye',
@params =null,
--提示
@hints =N'OPTION(OPTIMIZE FOR(@vacationhours=''99''))'

 

 

 清除執行計划:執行(會參考上面指定的執行計划)

exec p_querye 2

 

 存儲過程重編譯:

 

臨時結果集:

定義跟蹤的模板:

一:使用物理表進行臨時結果集

--1.做一張物理表
create procedure p_physicaltb
as
CREATE TABLE PhysicalTB(
	[SalesOrderID] [int] NOT NULL,
	[SalesOrderDetailID] [int]  NOT NULL,
	[CarrierTrackingNumber] [nvarchar](25) NULL,
	[OrderQty] [smallint] NOT NULL,
	[ProductID] [int] NOT NULL,
	[SpecialOfferID] [int] NOT NULL,
	[UnitPrice] [money] NOT NULL,
	[UnitPriceDiscount] [money] NOT NULL,
	[LineTotal] [numeric](38, 6) NOT NULL,
	[rowguid] [uniqueidentifier] NOT NULL,
	[ModifiedDate] [datetime] NOT NULL
) 
insert into PhysicalTB select * from OrderDetail
select * from PhysicalTB

set statistics time on
exec p_physicaltb   --cpu:391  total:1762
set statistics time off 

 跟蹤的情況:

 

 刪除之后再次創建執行。

物理表每次執行都會有重編譯的過程(不建議使用物理表來存儲臨時結果集)

 

第二種方式:

臨時表存儲臨時結果集

create procedure p_temptb
as
CREATE TABLE #PhysicalTB(
	[SalesOrderID] [int] NOT NULL,
	[SalesOrderDetailID] [int]  NOT NULL,
	[CarrierTrackingNumber] [nvarchar](25) NULL,
	[OrderQty] [smallint] NOT NULL,
	[ProductID] [int] NOT NULL,
	[SpecialOfferID] [int] NOT NULL,
	[UnitPrice] [money] NOT NULL,
	[UnitPriceDiscount] [money] NOT NULL,
	[LineTotal] [numeric](38, 6) NOT NULL,
	[rowguid] [uniqueidentifier] NOT NULL,
	[ModifiedDate] [datetime] NOT NULL
) 
insert into #PhysicalTB select * from OrderDetail
select * from #PhysicalTB
drop table #PhysicalTB

set statistics time on
exec p_temptb  --cpu:110  total:1494
set statistics time off

sp_helpdb 'tempdb'--16064,768

 第一次執行時重新編譯,第二次就不會重新編譯了。

用到了tempdb臨時表:

 

 第三種方式:表變量存儲臨時結果集

--表變量存儲臨時結果集
create procedure p_tabletb
as
--申明表變量
declare @PhysicalTB table(
	[SalesOrderID] [int] NOT NULL,
	[SalesOrderDetailID] [int]  NOT NULL,
	[CarrierTrackingNumber] [nvarchar](25) NULL,
	[OrderQty] [smallint] NOT NULL,
	[ProductID] [int] NOT NULL,
	[SpecialOfferID] [int] NOT NULL,
	[UnitPrice] [money] NOT NULL,
	[UnitPriceDiscount] [money] NOT NULL,
	[LineTotal] [numeric](38, 6) NOT NULL,
	[rowguid] [uniqueidentifier] NOT NULL,
	[ModifiedDate] [datetime] NOT NULL
) 
insert into @PhysicalTB select * from OrderDetail
select * from @PhysicalTB

set statistics time on
exec p_tabletb  --cpu:110  total:1494
set statistics time off

sp_helpdb 'tempdb'--17064,768

 執行時不會重新編譯  

 

第四種方式:

--CTE(通用表表達式)存儲臨時結果集  完全放在內存中 不會操作任何數據庫中的東西
create procedure p_ctetb
as
begin
--會自動推斷數據類型
;with PhysicalTB(
	[SalesOrderID],
	[SalesOrderDetailID],
	[CarrierTrackingNumber],
	[OrderQty] ,
	[ProductID],
	[SpecialOfferID],
	[UnitPrice] ,
	[UnitPriceDiscount] ,
	[LineTotal] ,
	[rowguid] ,
	[ModifiedDate] 
) as (select * from OrderDetail)
--訪問通用表表達式
select * from PhysicalTB
end

 跟蹤的結果:

沒有重新編譯的過程,純粹操作內存。tempdb數據庫不會有任何的變化。

set statistics time on
exec p_ctetb  --cpu:100  total:1300
set statistics time off

sp_helpdb 'tempdb'--17064,768

 

高版本的通用表達式可以進行多次的使用:

create procedure p_ctetb1
as
begin
;with PhysicalTB(
	[SalesOrderID],
	[SalesOrderDetailID],
	[CarrierTrackingNumber],
	[OrderQty] ,
	[ProductID],
	[SpecialOfferID],
	[UnitPrice] ,
	[UnitPriceDiscount] ,
	[LineTotal] ,
	[rowguid] ,
	[ModifiedDate] 
) as (select * from OrderDetail)
select * from PhysicalTB
select * from PhysicalTB
end

exec p_ctetb1

 08之前的數據庫,只要把表達式在創建一次就可以了

 

臨時數據集的優化處理:

 

 

優化查詢:編譯指南。

--清空執行計划
dbcc freeproccache
select * from EmployeeOp where VacationHours>1 option(use plan N'
<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.2" Build="12.0.2000.8">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementText="select * from EmployeeOp where VacationHours>99" StatementId="1" StatementCompId="1" StatementType="SELECT" RetrievedFromCache="true" StatementSubTreeCost="0.00657038" StatementEstRows="1" StatementOptmLevel="FULL" QueryHash="0x7E06C77E90EB9FBB" QueryPlanHash="0x64478FC6152D2A83" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" CardinalityEstimationModelVersion="120" ParameterizedText="(@1 tinyint)SELECT * FROM [EmployeeOp] WHERE [VacationHours]>@1">
          <StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false" />
          <QueryPlan CachedPlanSize="40" CompileTime="6" CompileCPU="6" CompileMemory="232">
            <MemoryGrantInfo SerialRequiredMemory="0" SerialDesiredMemory="0" />
            <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="206857" EstimatedPagesCached="51714" EstimatedAvailableDegreeOfParallelism="2" />
            <RelOp NodeId="0" PhysicalOp="Nested Loops" LogicalOp="Inner Join" EstimateRows="1" EstimateIO="0" EstimateCPU="4.18e-006" AvgRowSize="830" EstimatedTotalSubtreeCost="0.00657038" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
              <OutputList>
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="BusinessEntityID" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="NationalIDNumber" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="LoginID" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="OrganizationNode" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="OrganizationLevel" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="JobTitle" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="BirthDate" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="MaritalStatus" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="Gender" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="HireDate" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="SalariedFlag" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="VacationHours" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="SickLeaveHours" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="CurrentFlag" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="rowguid" />
                <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="ModifiedDate" />
              </OutputList>
              <NestedLoops Optimized="0">
                <OuterReferences>
                  <ColumnReference Column="Bmk1000" />
                </OuterReferences>
                <RelOp NodeId="1" PhysicalOp="Index Seek" LogicalOp="Index Seek" EstimateRows="1" EstimateIO="0.003125" EstimateCPU="0.0001581" AvgRowSize="19" EstimatedTotalSubtreeCost="0.0032831" TableCardinality="290" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                  <OutputList>
                    <ColumnReference Column="Bmk1000" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="VacationHours" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="SickLeaveHours" />
                  </OutputList>
                  <IndexScan Ordered="1" ScanDirection="FORWARD" ForcedIndex="0" ForceSeek="0" ForceScan="0" NoExpandHint="0" Storage="RowStore">
                    <DefinedValues>
                      <DefinedValue>
                        <ColumnReference Column="Bmk1000" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="VacationHours" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="SickLeaveHours" />
                      </DefinedValue>
                    </DefinedValues>
                    <Object Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Index="[nc_Employee_vacationsickleave]" IndexKind="NonClustered" Storage="RowStore" />
                    <SeekPredicates>
                      <SeekPredicateNew>
                        <SeekKeys>
                          <StartRange ScanType="GT">
                            <RangeColumns>
                              <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="VacationHours" />
                            </RangeColumns>
                            <RangeExpressions>
                              <ScalarOperator ScalarString="(99)">
                                <Const ConstValue="(99)" />
                              </ScalarOperator>
                            </RangeExpressions>
                          </StartRange>
                        </SeekKeys>
                      </SeekPredicateNew>
                    </SeekPredicates>
                  </IndexScan>
                </RelOp>
                <RelOp NodeId="3" PhysicalOp="RID Lookup" LogicalOp="RID Lookup" EstimateRows="1" EstimateIO="0.003125" EstimateCPU="0.0001581" AvgRowSize="826" EstimatedTotalSubtreeCost="0.0032831" TableCardinality="290" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                  <OutputList>
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="BusinessEntityID" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="NationalIDNumber" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="LoginID" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="OrganizationNode" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="OrganizationLevel" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="JobTitle" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="BirthDate" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="MaritalStatus" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="Gender" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="HireDate" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="SalariedFlag" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="CurrentFlag" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="rowguid" />
                    <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="ModifiedDate" />
                  </OutputList>
                  <IndexScan Lookup="1" Ordered="1" ScanDirection="FORWARD" ForcedIndex="0" ForceSeek="0" ForceScan="0" NoExpandHint="0" Storage="RowStore">
                    <DefinedValues>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="BusinessEntityID" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="NationalIDNumber" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="LoginID" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="OrganizationNode" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="OrganizationLevel" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="JobTitle" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="BirthDate" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="MaritalStatus" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="Gender" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="HireDate" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="SalariedFlag" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="CurrentFlag" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="rowguid" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" Column="ModifiedDate" />
                      </DefinedValue>
                    </DefinedValues>
                    <Object Database="[HRDB]" Schema="[dbo]" Table="[EmployeeOp]" TableReferenceId="-1" IndexKind="Heap" Storage="RowStore" />
                    <SeekPredicates>
                      <SeekPredicateNew>
                        <SeekKeys>
                          <Prefix ScanType="EQ">
                            <RangeColumns>
                              <ColumnReference Column="Bmk1000" />
                            </RangeColumns>
                            <RangeExpressions>
                              <ScalarOperator ScalarString="[Bmk1000]">
                                <Identifier>
                                  <ColumnReference Column="Bmk1000" />
                                </Identifier>
                              </ScalarOperator>
                            </RangeExpressions>
                          </Prefix>
                        </SeekKeys>
                      </SeekPredicateNew>
                    </SeekPredicates>
                  </IndexScan>
                </RelOp>
              </NestedLoops>
            </RelOp>
            <ParameterList>
              <ColumnReference Column="@1" ParameterCompiledValue="(99)" />
            </ParameterList>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>


')  --表掃描

select * from sys.dm_exec_cached_plans
select * from sys.dm_exec_sql_text
select * from  sys.dm_exec_query_plan
select * from EmployeeOp where VacationHours>99  -- 索引
select c.plan_handle,p.text from sys.dm_exec_cached_plans as c cross apply  sys.dm_exec_sql_text(c.plan_handle) as p

select * from  sys.dm_exec_query_plan(0x06000A00CD253E14207CA0290200000001000000000000000000000000000000000000000000000000000000)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM