Avatar billede gadebarnet Nybegynder
20. april 2005 - 14:55 Der er 29 kommentarer og
1 løsning

query optimering

Jeg har denne query... Jeg syntes nu at det er noget langsom... Er der nogle der har nogle ideer til optimering.?

---
select top 10 tbl_profil.str_id as str_id,tbl_billeder.str_id as tbl_billeder_str_id,str_ext,str_køn from tbl_profil join tbl_profil_besøg on tbl_profil.str_id = tbl_profil_besøg.str_profil_id join tbl_billeder on tbl_profil.str_id = tbl_billeder.str_profil_id where tbl_profil.str_sidstelogin > (dateadd(mm,-1,getdate())) and tbl_profil.str_sidstelogin < getdate() and tbl_profil_besøg.str_dato < (dateadd(mm,-1,getdate())) and str_køn = 1 group by tbl_profil.str_id, tbl_billeder.str_id,str_ext,str_køn ORDER BY NEWID()
---
Avatar billede herman01753 Nybegynder
20. april 2005 - 15:15 #1
punkt 1: hvorfor har du en group by claus med?
punkt 2: hvorfor bruger du ikke inner join istede for join?
Avatar billede herman01753 Nybegynder
20. april 2005 - 15:18 #2
er det her hurtigere? har jo ikke lige noget testdata at lege med.

select top 10
tp.str_id as str_id,
tb.str_id as tbl_billeder_str_id,
str_ext,
1
from
tbl_profil tp
inner join tbl_profil_besøg tpb on tp.str_id = tpb.str_profil_id
inner join tbl_billeder tb on tp.str_id = tb.str_profil_id
where
    tp.str_sidstelogin > (dateadd(mm,-1,getdate()))
        and
    tp.str_sidstelogin < getdate()
    and
    tpb.str_dato < (dateadd(mm,-1,getdate()))
    and
    str_køn = 1
ORDER BY NEWID()
Avatar billede gadebarnet Nybegynder
20. april 2005 - 15:19 #3
1 fordi at der ikke må komme dbl poste, da en profil kan have flere billeder.
2 det ved jeg ik... Hvad er ideen ved at bruge inner join ?
Avatar billede herman01753 Nybegynder
20. april 2005 - 15:22 #4
hvis det er nødvendigt kan du jo putte din group by clause på igen.
**********
select top 10
tp.str_id as str_id,
tb.str_id as tbl_billeder_str_id,
str_ext,
str_køn
from
tbl_profil tp
inner join tbl_profil_besøg tpb on tp.str_id = tpb.str_profil_id
inner join tbl_billeder tb on tp.str_id = tb.str_profil_id
where
    tp.str_sidstelogin > (dateadd(mm,-1,getdate()))
        and
    tp.str_sidstelogin < getdate()
    and
    tpb.str_dato < (dateadd(mm,-1,getdate()))
    and
    str_køn = 1
group by tp.str_id, tb.str_id,str_ext,str_køn
ORDER BY NEWID()
*********
en anden ting er at du rent faktisk vælger at pille str_køn ud af din query, men i din where clause skriver du explicit at den skal være 1, så du kunne i  din select skrive select bla,bla,bla,1 from ....
Avatar billede herman01753 Nybegynder
20. april 2005 - 15:25 #5
hvis det er nødvendigt kan du jo putte din group by clause på igen.
**********
select top 10
tp.str_id as str_id,
tb.str_id as tbl_billeder_str_id,
str_ext,
str_køn
from
tbl_profil tp
inner join tbl_profil_besøg tpb on tp.str_id = tpb.str_profil_id
inner join tbl_billeder tb on tp.str_id = tb.str_profil_id
where
    tp.str_sidstelogin > (dateadd(mm,-1,getdate()))
        and
    tp.str_sidstelogin < getdate()
    and
    tpb.str_dato < (dateadd(mm,-1,getdate()))
    and
    str_køn = 1
group by tp.str_id, tb.str_id,str_ext,str_køn
ORDER BY NEWID()
*********
en anden ting er at du rent faktisk vælger at pille str_køn ud af din query, men i din where clause skriver du explicit at den skal være 1, så du kunne i  din select skrive select bla,bla,bla,1 from ....
Avatar billede gadebarnet Nybegynder
20. april 2005 - 15:26 #6
ser, det der må du lige forklare... det med køn?
Avatar billede herman01753 Nybegynder
20. april 2005 - 15:30 #7
du skriver
select top 10 .....,str_køn
from ...
where str_køn = 1 .....

fordi du ved at str_køn altid vil være 1 i denne query, kan du lige så godt skrive
select top 10 .....,1 as str_køn
from ...
where str_køn = 1 .....
Avatar billede arne_v Ekspert
20. april 2005 - 18:13 #8
herman>

Hvad mener du med:

#punkt 2: hvorfor bruger du ikke inner join istede for join?

?

(join uden angivelse af type er inner join)
Avatar billede gadebarnet Nybegynder
21. april 2005 - 08:56 #9
Nu ser den sådan her ud...

Men jeg syntes stadigvæk at den er langsom... Nogle tips?

---
select top 10
tp.str_id as str_id,
tb.str_id as tbl_billeder_str_id,
str_ext, 1 from tbl_profil tp
inner join tbl_profil_besøg tpb on tp.str_id = tpb.str_profil_id
inner join tbl_billeder tb on tp.str_id = tb.str_profil_id
where tp.str_sidstelogin > (dateadd(mm,-1,getdate()))
and tp.str_sidstelogin < getdate() and tpb.str_dato < (dateadd(mm,-1,getdate()))
and str_køn = 0
group by tp.str_id ,tb.str_id, str_ext
ORDER BY NEWID()
---
Avatar billede herman01753 Nybegynder
21. april 2005 - 09:51 #10
prøv med følgende. du skal have db med som står sidt i sætningen.

*******
select top 10 * from (select
DISTINCT tp.str_id as str_id,
tb.str_id as tbl_billeder_str_id,
str_ext, 1 from tbl_profil tp
inner join tbl_profil_besøg tpb on tp.str_id = tpb.str_profil_id
inner join tbl_billeder tb on tp.str_id = tb.str_profil_id
where tp.str_sidstelogin > (dateadd(mm,-1,getdate()))
and tp.str_sidstelogin < getdate() and tpb.str_dato < (dateadd(mm,-1,getdate()))
and str_køn = 0

ORDER BY NEWID())db
******
Avatar billede gadebarnet Nybegynder
21. april 2005 - 09:59 #11
Ja, du glemmer min group by... Det er meget vigtigt at profiler kun optræder 1 gang, selv om de har flere billeder...

Og hvad/hvor kommer det db fra?
Avatar billede herman01753 Nybegynder
21. april 2005 - 10:00 #12
db er synonym for min subquery, og skal være på for at man kan lave en sådan. Hvis du har et script til at lave tabellerne, og til at fylde nogle testdata i, vil jeg gerne sidde og lege lidt med det, men det kræver nok jeg har nogle faktiske data at pille ved, så jeg kan se hvor jeg kan optimere, og om det er muligt ast lave en række queries, som så kan lægges sammen.
Avatar billede gadebarnet Nybegynder
21. april 2005 - 10:04 #13
Jeg har ikke lige noget script...

Hvis jeg kendte dig bedre ville jeg give dig adgang til min sql, men du kan jo være "en være en" så det går nok ikke...

Men problemet er min group by... Den sløver det en hel del ned...
Avatar billede gadebarnet Nybegynder
21. april 2005 - 10:13 #14
Den giver en
The ORDER BY clause is invalid in views, inline functions, derived tables, and subqueries, unless TOP is also specified.
Avatar billede herman01753 Nybegynder
21. april 2005 - 10:14 #15
jeg sidder lige og bikser med noget, hvis du går ind på din SQL server i enterprize manager, og vælger den rigtige database, og herefter diagram. Herefter højreklikker du på den blanke flade og vælger nyt diagram.
Så ltager du de tabeller som har relation til dette query, og vupti så har di et diagram over tabellerne. herefter markerer du alle tabellerne, højreklikker på en af tabellernes top bar, og vælger all tasks | generate sql script.

herefter kan du så få lavet et script som opretter tabellerne, som jeg så kan kigge på. dog uden data, men det væsentligste er også at jeg kan se om jeg kan få optimeret søgningen.
Avatar billede gadebarnet Nybegynder
21. april 2005 - 10:18 #16
ahhh, super...

" Det vidste jeg faktisk godt "

---
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tbl_betalt_profilbesøg]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tbl_betalt_profilbesøg]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tbl_billeder]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tbl_billeder]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tbl_profil]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tbl_profil]
GO

CREATE TABLE [dbo].[tbl_betalt_profilbesøg] (
    [uniqueid] [int] IDENTITY (1, 1) NOT FOR REPLICATION  NOT NULL ,
    [str_måned] [int] NULL ,
    [str_år] [int] NULL ,
    [str_profil_id] [uniqueidentifier] NULL ,
    [str_dato] [datetime] NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[tbl_billeder] (
    [uniqueid] [int] IDENTITY (1, 1) NOT FOR REPLICATION  NOT NULL ,
    [str_id] [uniqueidentifier] NULL ,
    [str_type] [int] NULL ,
    [str_dato] [datetime] NULL ,
    [str_sted] [int] NULL ,
    [str_overskrift] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_aktiv] [bit] NULL ,
    [str_ext] [nvarchar] (50) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_profil_id] [uniqueidentifier] NULL ,
    [str_profil] [int] NULL ,
    [str_mappe_id] [uniqueidentifier] NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[tbl_profil] (
    [uniqueid] [int] IDENTITY (1, 1) NOT FOR REPLICATION  NOT NULL ,
    [str_id] [uniqueidentifier] NULL ,
    [str_brugernavn] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_password] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_fornavn] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_efternavn] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_fødselsdag] [datetime] NULL ,
    [str_køn] [bit] NULL ,
    [str_telefon] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_email] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_region] [int] NULL ,
    [str_beskrivelse] [ntext] COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_aktiv] [bit] NULL ,
    [str_admin_upload] [bit] NULL ,
    [str_admin_edit_regioner] [bit] NULL ,
    [str_admin_edit_steder] [bit] NULL ,
    [str_admin_edit_brugere] [bit] NULL ,
    [str_admin_edit_banner] [bit] NULL ,
    [str_admin_edit_events] [bit] NULL ,
    [str_admin_edit_fotograf] [bit] NULL ,
    [str_billede] [uniqueidentifier] NULL ,
    [str_oprettet] [datetime] NULL ,
    [str_oldid] [int] NULL ,
    [str_enablepages] [bit] NULL ,
    [str_højde] [int] NULL ,
    [str_vægt] [int] NULL ,
    [str_øjenfarve] [int] NULL ,
    [str_partnerstatus] [int] NULL ,
    [str_lederefter] [int] NULL ,
    [str_hårfarve] [int] NULL ,
    [str_sidstelogin] [datetime] NULL ,
    [str_status_antallæst] [int] NULL ,
    [str_pic] [bit] NULL ,
    [str_seprofil] [bit] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

---
Avatar billede herman01753 Nybegynder
21. april 2005 - 10:19 #17
du skal flytte order by clause'n ud bagefter db, det er min fejl.
Avatar billede gadebarnet Nybegynder
21. april 2005 - 10:21 #18
se'følig...
Avatar billede gadebarnet Nybegynder
21. april 2005 - 10:22 #19
så heddder deT:

No column was specified for column 4 of 'db'.


måske jeg skulle læse noget mere om det her... Jeg syntes bare jeg har læs MEGET de sidste mange år...
Avatar billede herman01753 Nybegynder
21. april 2005 - 10:22 #20
når du laver et script, kan du vælge fanebladet options, og tjekke feltet script primarykeys, foreign keys default and ...

Hvis du sætter den på, så har jeg også relationerne med, hvilket vil gøre mig glad i denne situation ;)
Avatar billede gadebarnet Nybegynder
21. april 2005 - 10:25 #21
klart...
---
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tbl_betalt_profilbesøg]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tbl_betalt_profilbesøg]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tbl_billeder]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tbl_billeder]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tbl_profil]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tbl_profil]
GO

CREATE TABLE [dbo].[tbl_betalt_profilbesøg] (
    [uniqueid] [int] IDENTITY (1, 1) NOT FOR REPLICATION  NOT NULL ,
    [str_måned] [int] NULL ,
    [str_år] [int] NULL ,
    [str_profil_id] [uniqueidentifier] NULL ,
    [str_dato] [datetime] NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[tbl_billeder] (
    [uniqueid] [int] IDENTITY (1, 1) NOT FOR REPLICATION  NOT NULL ,
    [str_id] [uniqueidentifier] NULL ,
    [str_type] [int] NULL ,
    [str_dato] [datetime] NULL ,
    [str_sted] [int] NULL ,
    [str_overskrift] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_aktiv] [bit] NULL ,
    [str_ext] [nvarchar] (50) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_profil_id] [uniqueidentifier] NULL ,
    [str_profil] [int] NULL ,
    [str_mappe_id] [uniqueidentifier] NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[tbl_profil] (
    [uniqueid] [int] IDENTITY (1, 1) NOT FOR REPLICATION  NOT NULL ,
    [str_id] [uniqueidentifier] NULL ,
    [str_brugernavn] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_password] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_fornavn] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_efternavn] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_fødselsdag] [datetime] NULL ,
    [str_køn] [bit] NULL ,
    [str_telefon] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_email] [nvarchar] (255) COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_region] [int] NULL ,
    [str_beskrivelse] [ntext] COLLATE Danish_Norwegian_CI_AS NULL ,
    [str_aktiv] [bit] NULL ,
    [str_admin_upload] [bit] NULL ,
    [str_admin_edit_regioner] [bit] NULL ,
    [str_admin_edit_steder] [bit] NULL ,
    [str_admin_edit_brugere] [bit] NULL ,
    [str_admin_edit_banner] [bit] NULL ,
    [str_admin_edit_events] [bit] NULL ,
    [str_admin_edit_fotograf] [bit] NULL ,
    [str_billede] [uniqueidentifier] NULL ,
    [str_oprettet] [datetime] NULL ,
    [str_oldid] [int] NULL ,
    [str_enablepages] [bit] NULL ,
    [str_højde] [int] NULL ,
    [str_vægt] [int] NULL ,
    [str_øjenfarve] [int] NULL ,
    [str_partnerstatus] [int] NULL ,
    [str_lederefter] [int] NULL ,
    [str_hårfarve] [int] NULL ,
    [str_sidstelogin] [datetime] NULL ,
    [str_status_antallæst] [int] NULL ,
    [str_pic] [bit] NULL ,
    [str_seprofil] [bit] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

ALTER TABLE [dbo].[tbl_billeder] ADD
    CONSTRAINT [DF_tbl_billeder_str_id] DEFAULT (newid()) FOR [str_id]
GO

ALTER TABLE [dbo].[tbl_profil] ADD
    CONSTRAINT [DF_tbl_profil_str_id] DEFAULT (newid()) FOR [str_id],
    CONSTRAINT [DF_tbl_profil_str_aktiv] DEFAULT (0) FOR [str_aktiv],
    CONSTRAINT [DF_tbl_profil_str_admin_upload] DEFAULT (0) FOR [str_admin_upload],
    CONSTRAINT [DF_tbl_profil_str_admin_edit_regioner] DEFAULT (0) FOR [str_admin_edit_regioner],
    CONSTRAINT [DF_tbl_profil_str_admin_edit_steder] DEFAULT (0) FOR [str_admin_edit_steder],
    CONSTRAINT [DF_tbl_profil_str_admin_edit_brugere] DEFAULT (0) FOR [str_admin_edit_brugere],
    CONSTRAINT [DF_tbl_profil_str_admin_edit_banner] DEFAULT (0) FOR [str_admin_edit_banner],
    CONSTRAINT [DF_tbl_profil_str_admin_edit_events] DEFAULT (0) FOR [str_admin_edit_events],
    CONSTRAINT [DF_tbl_profil_str_admin_edit_fotograf] DEFAULT (0) FOR [str_admin_edit_fotograf],
    CONSTRAINT [DF_tbl_profil_str_enablepages] DEFAULT (0) FOR [str_enablepages],
    CONSTRAINT [DF_tbl_profil_str_seprofil] DEFAULT (1) FOR [str_seprofil]
GO

---

bedre???
Avatar billede herman01753 Nybegynder
21. april 2005 - 11:31 #22
næh, du har jo ingen relationer imellem tabellerne med fremmednøgler, er det med vilje? Du bør nok lave fremmednølerne, som sikrer dig imod inkonsistente data, og dermed indirekte måske kan afhjælpe noget af dit hastighedsproblem.
Avatar billede herman01753 Nybegynder
21. april 2005 - 11:33 #23
hvad er forskellen på uniqueid og str_id i profil-tabellen? Det ser ud til der er en del normalisering at gør på tabellerne i forhold til de query du fyrede afsted til at starte med.
Avatar billede gadebarnet Nybegynder
21. april 2005 - 11:34 #24
???

Den første du skriver fatter jeg minus af.

og det andet er:

Det er IKKE mig der har startet denne opbygning, jeg arbejder vidre med noget... Men uniqueid er en int og str_id er uniqueid....
Avatar billede herman01753 Nybegynder
21. april 2005 - 11:46 #25
ok. jeg ser grundlæggende et problem i at du har en str_id, som kn være null, og som refererer til en anden tabel. prøv at lave en

select * from tbl_profil where str_id is null

normalt så joiner man tabeller sammen på deres primærnøgle. du er igang med at joine sammen på en anden kolonne. det betyder i praksis, at du kan have den samme str_id for flere forskellige profiler, da de ikke er unikke(selvom du bruger newid til at allokere dem med, kan man potentielt få ændre den til at være det samme som i en anden profil). Ved at lave relationer imellem tabeller med fremmednøgler, så sikre du at hvis du sletter en profil, vil den brokke sig over at det ligger data i andre tabeller, som refererer til denne profil. på den måde kan man rydde op i data, dermed mindske datamængden, og dermed øge performance.

læs evt. lidt om normaliser af databaser til 3NF(tredje normal form).
Grundlæggende bør data kun være afhngigt af primærnøglen, hvis andet er tilfældet bør den data splittes op i en tabel. Relationer imellem tabeller opretholdes med fremmednøgle i den nye tabel, som relaterer til primærnøglen i den oprindelige tabel.

håber det afklarede et par ting, ellers skriv igen.
Avatar billede gadebarnet Nybegynder
21. april 2005 - 12:01 #26
Kan du ikke kontakte mig på email

david@dollas.dk (omkring at give dig adgang til min database?)
Avatar billede herman01753 Nybegynder
21. april 2005 - 12:33 #27
jep, er lige kommet fra frokost. to sek
Avatar billede ldanielsen Nybegynder
21. april 2005 - 16:57 #28
Herman har ret, det handler næsten sikkert om indexer.

ALLE  tabeller skal have en primær nøgle, og det har dine ikke. Når du laver en primær nøgle oprettes der samtidig et index på kolonnen. Desuden skal du enten lave indexer for de kolonner du vil joine på, eller lave fremmednøgler. Og sidst kan de være en god ide at lave indexer på de kolonner du bruger i WHERE, ORDER BY og GROUP BY.

Jeg har selv oplevet at en query blev kørt på 5% af den oprindelige tid, bare fordi jeg lavede et par indexer.
Avatar billede ldanielsen Nybegynder
21. april 2005 - 16:58 #29
Hvis du skriver JOIN i stedet for INNER JOIN betyder det det samme.
Avatar billede herman01753 Nybegynder
27. april 2005 - 11:36 #30
Var min hjælp tilstrækkelig?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester