# Die ältesten 100 Einträge löschen



## deinertsche (30. Januar 2006)

Hallo!
Ich würde gerne immer wenn ein neuer Wert eingefügt wird (und meine Tabelle mehr als 5000 Einträge hat), die ältesten 100 Einträge löschen.

Ich hatte mir das so funktioniert aber ORDER BY scheint mit DELETE nicht zu funktionieren:

mysql_query("DELETE FROM logtable ORDER BY date LIMIT 100");

Geht das irgendwie auf elegantem Wege, also ohne dass ich erst nochmal das Datum bestimmen muss und dann in Abhängigkeit vom (...WHERE date<xyz ) Datum löschen muss?

Achja, ich verwende php/mysql.


----------



## ManicMarble (30. Januar 2006)

Hallo,

bei MySQL >= 4.1 (Subqueries) müsste dies funktionieren:

```
DELETE FROM `tabelle`
WHERE `id` < (SELECT `id` FROM `tabelle` ORDER BY `id` LIMIT 100,1)
```
sofern Deine Tabelle eine auto_increment-Id-Spalte hat.

Wenn Du mit aller Gewalt eine reine SQL-Lösung haben willst (es gibt so Freaks), dann kannst Du auch noch die "nur wenn Gesamtanzahl > 5000"-Bedingung da mit reinquetschen, etwa in der Art:

```
DELETE FROM `tabelle`
WHERE
      `id` < (SELECT `id` FROM `tabelle` ORDER BY `id` LIMIT 100,1)
  AND (SELECT COUNT(*) FROM `tabelle`) > 5000
```
Das muss aber wirklich nicht sein, 

Grüße,
_Martin_


----------



## hpvw (30. Januar 2006)

```
delete from tabelle 
order by id # Wenn Du einen Timestamp in der Tabelle hast, ist das natürlich noch eleganter
limit 100
```
Siehe auch: Handbuch

Gruß hpvw

EDIT: Ich habe die 5000 vergessen. Wie ManicMarble schon erwähnt hat, ist dazu ein Subquery nötig, was erst ab MySQL 4.1 möglich ist: 
	
	
	



```
delete from tabelle 
where (select count(*) from tabelle) > 5000
order by id # Wenn Du einen Timestamp in der Tabelle hast, ist das natürlich noch eleganter
limit 100
```
Ich bin mir nicht sicher, wie MySQL bei sowas intern arbeitet. Möglicherweise sind 2 Queries, also erst das Select, eine Abfrage in der Anwendungssprache und dann ggf. des Delete schneller.


----------



## ManicMarble (30. Januar 2006)

@hpvw:
Hast recht, das mit ORDER BY ... LIMIT 100 ist natürlich viel eleganter und kommt ohne Subquery aus. Ich hatte mich von deinertsche's Aussage, ORDER BY würde mit DELETE nicht richtig funktionieren, blenden lassen. Das funktioniert aber, ich habe das selbst schön öfters so gemacht (mit MySQL ab 4.0 auf jeden Fall).

Das mit den 5000 im SQL ist höchstwahrscheinlich nicht so doll, ich fürchte, dass dadurch für jeden der 100 Datensätze das Subquery immer neu ausgeführt wird, was sicher nicht besonderes performant wäre. Es sei denn, der MySQL-Optimizer kapiert selbstständig, was hier passieren soll (wäre mal interessant, das auszuprobieren). Also ich würd's wohl eher im Skript machen...

_Martin_


----------



## hpvw (30. Januar 2006)

ManicMarble hat gesagt.:
			
		

> Das mit den 5000 im SQL ist höchstwahrscheinlich nicht so doll, ich fürchte, dass dadurch für jeden der 100 Datensätze das Subquery immer neu ausgeführt wird, was sicher nicht besonderes performant wäre. Es sei denn, der MySQL-Optimizer kapiert selbstständig, was hier passieren soll (wäre mal interessant, das auszuprobieren). Also ich würd's wohl eher im Skript machen...


Der MySQL-Optimizer ist besser als sein Ruf, aber der Worst-Case wäre wohl, wenn das Select 5000 mal ausgeführt, weil immer noch keine 100 Datensätze gelöscht wurden. Im besten Fall erkennt MySQL, dass der eine Ausdruck nie wahr wird und somit die gesamte Bedingung auch nicht. Meine Vermutung ist, zumindest mit aktiviertem Query-Cache, dass das Select einmal ausgeführt wird und bis zu 4999 mal die Bedingung false=true geprüft wird.
Für einen Performancetest habe ich gerade keine Zeit, interessant wäre es auf jeden Fall.

Gruß hpvw


----------



## deinertsche (1. Februar 2006)

Danke für Eure Antworten. Mit Subqueries wärs mir auch klar gewesen aber leider wird hier auf der Arbeit MySQL 3.23 verwendet und damit werden weder Subqueries noch DELETE ORDER BY unterstützt.

MySQL-Handbuch:
"ORDER BY can be used with DELETE beginning with MySQL 4.0.0. "

Ich werd mir halt ne php-Lösung drumrumbasteln. Hatte gedacht, es würde vielleicht eleganter gehen aber das geht wohl nur mit ner aktuellen MySQL-Version.

Trotzdem Danke für eure Hilfe!


----------

