Kom ihåg mig?
Home Menu

Menu


beror detta fel på gammal MySQL-version?

Ämnesverktyg Visningsalternativ
Oläst 2005-08-12, 12:36 #1
koalas avatar
koala koala är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: Sep 2004
Inlägg: 1 154
koala koala är inte uppkopplad
Har WN som tidsfördriv
koalas avatar
 
Reg.datum: Sep 2004
Inlägg: 1 154
Utvecklar grejer till en kund som har webbhotell hos cliche. Har använt version 4.x när jag utvecklat koden, men upptäckte att cliche har version 3. Misstänker att versionsskillnaden är boven i dramat, eller är jag ute och cyklar här? Som sagt använder jag själv 4.x och får inte något felmeddelande av följande query (ej heller på scorpionshops server), men på cliche blir det fel:

Kod:
You have an error in your SQL syntax near '(SELECT p.category_id cId,
  	COUNT(p.product_id) as category_product_count
 ' at line 4
Whole query:
	SELECT c.*, t.category_product_count
  	FROM shop_category c
  	LEFT JOIN
  	(SELECT p.category_id cId,
  	COUNT(p.product_id) as category_product_count
  	FROM shop_product p
  	GROUP BY p.category_id
  	) t
  	ON
  	t.cId = c.category_id
Databasen är rätt så identisk på cliches server och min, bortsett från att jag var tvungen att modifiera lite grejer som tydligen inte stöds i MySQL 3.x såsom att jag ändrat tabellerna från:
Kod:
CREATE TABLE `shop_product` (
 `product_id` int(11) unsigned NOT NULL auto_increment,
 `category_id` int(11) NOT NULL default '0',
 `product_price` decimal(15,4) NOT NULL default '0.0000',
 `product_is_call_for_price` tinyint(1) NOT NULL default '0',
 `product_is_always_free_shipping` tinyint(1) NOT NULL default '0',
 `product_date_added` datetime NOT NULL default '0000-00-00 00:00:00',
 `product_date_modified` datetime default NULL,
 `product_date_available` datetime default NULL,
 `product_image` tinytext,
 `product_quantity` int(11) NOT NULL default '0',
 `product_custom_id` varchar(32) default NULL,
 PRIMARY KEY (`product_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
till:

Kod:
CREATE TABLE `shop_product` (
 `product_id` int(11) unsigned NOT NULL auto_increment,
 `category_id` int(11) NOT NULL default '0',
 `product_price` decimal(15,4) NOT NULL default '0.0000',
 `product_is_call_for_price` tinyint(1) NOT NULL default '0',
 `product_is_always_free_shipping` tinyint(1) NOT NULL default '0',
 `product_date_added` datetime NOT NULL default '0000-00-00 00:00:00',
 `product_date_modified` datetime default NULL,
 `product_date_available` datetime default NULL,
 `product_image` tinytext,
 `product_quantity` int(11) NOT NULL default '0',
 `product_custom_id` varchar(32) default NULL,
 PRIMARY KEY (`product_id`)
) TYPE=MyISAM;
Tycker inte att denna ändring bör påverka...

Så här ser shop_category ut:

Kod:
CREATE TABLE `shop_category` (
 `category_id` int(11) unsigned NOT NULL auto_increment,
 `category_parent_id` int(11) NOT NULL default '0',
 `category_sort_order` int(3) default NULL,
 `category_image` varchar(128) default '',
 `category_date_added` datetime default NULL,
 `category_date_modified` datetime default NULL,
 PRIMARY KEY (`category_id`),
 KEY `NewIndex` (`category_parent_id`,`category_id`)
) TYPE=MyISAM;

Mycket(!) tacksam för information om vad felet beror på!





Lite kul kan man väl ha åt följande mail? Varför ens svara när man inte svarar på kundens frågor? (Ok jag vet att man får vad man betalar för, och jag ska försöka få kunden att byta webbhotell...)
Citat:
Hej X

Det är inte något jag vet av, men det kan vära att det kommer engång
till näste år.

Vänliga hälsningar
X X

-------------------------------
Cliche Webhosting Sweden
X
Tlf. X
Fax. X
-------------------------------

x wrote:
> Hej, jag ser att MySQL-versionen som används på mitt konto är: MySQL 3.23.56
>
> Jag skulle behöva version 4.x för en vidareutveckling. Är det möjligt att ordna detta på något sätt? Eller blir vi tvungna att flytta till ett annat webbhotell?
>
> MVH X
koala är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-08-12, 12:42 #2
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
Citat:
beror detta fel på gammal MySQL-version?
med största sannolikhet ja.
Subquerys kom ganska sent i mysql (v4.1 som det verkar).

http://dev.mysql.com/doc/mysql/en/rewritin...subqueries.html
eg0master är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-08-12, 13:21 #3
koalas avatar
koala koala är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: Sep 2004
Inlägg: 1 154
koala koala är inte uppkopplad
Har WN som tidsfördriv
koalas avatar
 
Reg.datum: Sep 2004
Inlägg: 1 154
Som jag misstänkte då med andra ord... Vill inte ändra min kod för att bli bakåtkompatibel egentligen. Men är det kanske dumt att använda subqueries överhuvudtaget? (Eftersom det nu kom så sent i MySQL...)
koala är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-08-12, 13:41 #4
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
Om man använder mysql är subquerys dumt (eftersom det bara stöds i de senaste versionerna och mysqlinstallationer har en tendens att inte vara helt up-to-date), men annars är det ju ett utmärkt sätt att låta databasen göra jobbet istf att göra det själv i kod.

Dock är väl din fråga knappast något som verkligen kräver en subquery... Det gör den bara onödigt komplicerad.
Kod:
 SELECT c.category_id, c.category_name, count(*)
FROM shop_category c, shop_product p
WHERE c.category_id = p.category_id
GROUP BY c.category_id, c.category_name
Det är ju bara listan i group by som måste innehålla alla kolumner från shop_category du skall plocka ut (och sluta göra select * - det är en dålig ovana - ange alltid vad du vill ha).
Min query blir dessutom sannolikt snabbare eftersom den slipper göra en subquery.
eg0master är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-08-12, 18:10 #5
Starwebs avatar
Starweb Starweb är inte uppkopplad
Flitig postare
 
Reg.datum: Jan 2004
Inlägg: 332
Starweb Starweb är inte uppkopplad
Flitig postare
Starwebs avatar
 
Reg.datum: Jan 2004
Inlägg: 332
Citat:
Originally posted by eg0master@Aug 12 2005, 12:41
(och sluta göra select * - det är en dålig ovana - ange alltid vad du vill ha).
Min query blir dessutom sannolikt snabbare eftersom den slipper göra en subquery.
Gör ej heller count(*), det påverkar också negativt. Skriv då exakt vad du vill count:a. Att föredra är såfall databasens id, tex count(c.category_id), om det nu är det du ska beräkna...
Starweb är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-08-12, 21:12 #6
grazzy grazzy är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Mar 2004
Inlägg: 3 471
grazzy grazzy är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Mar 2004
Inlägg: 3 471
OT:
Kod:
#!/usr/local/bin/perl -w

use DBI;

require ("database_login.pl");
my $blah = subnet_connect();
my $dbh = $$blah;
######

my ($sql,$sth,$sql2,$sth2,$t1,$t2,$t3,$t4,$iters);
$iters = 100000;
$sql = 'SELECT SQL_NO_CACHE COUNT(*) FROM article';
$sth = $dbh->prepare($sql);

$t1 = time();
for($i=0;$i<$iters;$i++) {
    $sth->execute();
}
$t2 = time();
$sth->finish();

$sql2 = 'SELECT SQL_NO_CACHE COUNT(id) FROM article';
$sth = $dbh->prepare($sql2);
$t3 = time();
for($i=0;$i<$iters;$i++) {
    $sth->execute();
}
$t4 = time();
$sth->finish();
print "COUNT(*) " . ($t2-$t1) . " seconds\n";
print "COUNT(id) " . ($t4-$t3) . " seconds\n";
$dbh->disconnect();
Tabellen har ca 1 miljon rader och har ett par rätt stora fält.

Körningar (3):
Kod:
COUNT(*) 10.6 seconds
COUNT(id) 11 seconds
Testade även att selecta * mot att selecta alla fält. Här körde jag en LIMIT 100 iom att bandbredden blir en flaskhals annars. 1000 iterationer. 4 körningar
Kod:
* 5 seconds
fält 5.8 seconds
Vid en första anblick ser detta försumbart ut, dock blir siffrorna annorlunda när man tittar närmare på dem.

100,000 frågor på en tabell med 1,000,000 rader ger en diff på ungefär 3,6% (om jag kommer ihåg min lågstadiematte rätt).

I fallet med SELECT är skillnaden större, nämligen 13,8% med 1000 iterationer över 100 rader (den här växer då rätt snabbt till en betydande skillnad).
grazzy är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-08-12, 23:17 #7
koalas avatar
koala koala är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: Sep 2004
Inlägg: 1 154
koala koala är inte uppkopplad
Har WN som tidsfördriv
koalas avatar
 
Reg.datum: Sep 2004
Inlägg: 1 154
Citat:
Originally posted by eg0master@Aug 12 2005, 13:41
Om man använder mysql är subquerys dumt (eftersom det bara stöds i de senaste versionerna och mysqlinstallationer har en tendens att inte vara helt up-to-date), men annars är det ju ett utmärkt sätt att låta databasen göra jobbet istf att göra det själv i kod.
Dock är väl din fråga knappast något som verkligen kräver en subquery... Det gör den bara onödigt komplicerad.
Kod:
 SELECT c.category_id, c.category_name, count*
FROM shop_category c, shop_product p
WHERE c.category_id = p.category_id
GROUP BY c.category_id, c.category_name
Det är ju bara listan i group by som måste innehålla alla kolumner från shop_category du skall plocka ut (och sluta göra select * - det är en dålig ovana - ange alltid vad du vill ha).
Min query blir dessutom sannolikt snabbare eftersom den slipper göra en subquery.

Det där tipset är jag mycket tacksam för, och ska byta ut min query. Nästan så man skäms ju

Jag kommer inte att lyssna på ditt tips om att specifikt ange fält, utan kör på *. Visserligen håller jag med dig om att det i teorin är bäst att ange sina fält. Dock inte i praktiken (Jag vet vad alla fält heter ändå. Det går även att justera detta i efterhand om man känner för det, men för att spara tid (och även få snabbare querys -- källa: grazzy) kör jag * just nu...)

EDIT: Det finns ett litet problem när jag byter till din query: De kategorier som är tomma (dvs det saknas produkter i dem) kommer inte med nu, vilket jag vill att de ska göra, och få en product_count på 0 eller NULL... Ska fundera på detta efter "frukost"...
koala är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-08-13, 01:24 #8
grazzy grazzy är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Mar 2004
Inlägg: 3 471
grazzy grazzy är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Mar 2004
Inlägg: 3 471
Det brukar man lösa med LEFT JOINS vs INNER JOINS.. Du använder nu en innerjoin, det innebär att raden bara visas om det finns ett fält i båda tabellerna du joinar som stämmer. En left tar alltid med om det finns något i den vänstra.

Hmm, jag inser just att mina benchmarks visar resulta tvärtom mot all vedertagen kunskap. Kan någon vara snäll att peka ut vad jag har gjort för fel, eller uppvisa resultat som påvisar annorlunda?
grazzy är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-08-13, 02:57 #9
koalas avatar
koala koala är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: Sep 2004
Inlägg: 1 154
koala koala är inte uppkopplad
Har WN som tidsfördriv
koalas avatar
 
Reg.datum: Sep 2004
Inlägg: 1 154
Citat:
Originally posted by grazzy@Aug 13 2005, 01:24
Det brukar man lösa med LEFT JOINS vs INNER JOINS.. Du använder nu en innerjoin, det innebär att raden bara visas om det finns ett fält i båda tabellerna du joinar som stämmer. En left tar alltid med om det finns något i den vänstra.
Hmm, jag inser just att mina benchmarks visar resulta tvärtom mot all vedertagen kunskap. Kan någon vara snäll att peka ut vad jag har gjort för fel, eller uppvisa resultat som påvisar annorlunda?

Ja just ja, jag tänkte inte på att det faktiskt är en JOIN eftersom det inte står JOIN någonstans i queryn Så här skrev jag nu:
Kod:
SELECT c.*, count(p.product_id) category_product_count
FROM shop_category c
LEFT JOIN shop_product p 
ON c.category_id = p.category_id
GROUP BY c.category_id
och det bör fungera bra... (har inte provat ännu dock, men räknar med nemas problemas).
koala är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 3 (0 medlemmar och 3 gäster)
 

Regler för att posta
Du får inte posta nya ämnen
Du får inte posta svar
Du får inte posta bifogade filer
Du får inte redigera dina inlägg

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 17:08.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson
 
Copyright © 2017