从包含数百万条记录的表中删除

时间:2010-02-13 14:46:01

标签: sql mysql

我正试图找到一种在InnoDB表上进行条件DELETE的方法,该表包含数百万条记录,而不会锁定它(因此不会使网站失效)。

我试图在mysql.com上找到相关信息,但无济于事。关于如何进行的任何提示?

3 个答案:

答案 0 :(得分:8)

我不认为没有锁定就可以删除。也就是说,我不认为锁定您要删除的记录是一个问题。什么问题是锁定其他行。

我在这里找到了关于该主题的一些信息:http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html

我建议的是尝试进行一百万次单行删除。我认为如果你在一次交易中做所有这些,性能不应该太大。所以你会得到类似的东西:

START TRANSACTION;

DELETE FROM tab WHERE id = 1;
..
..
DELETE FROM tab WHERE id = x;

COMMIT;

您可以通过执行类似

的操作生成所需的状态
SELECT CONCAT('DELETE FROM tab WHERE id = ', id)
FROM   tab
WHERE  <some intricate condition that selects the set you want to delete>

所以优于这种方法而不是:

DELETE FROM tab 
WHERE  <some intricate condition that selects the set you want to delete>

在第一种方法中,您只能锁定要删除的记录,而在第二种方法中,您可能会遇到锁定其他记录的风险,这些记录恰好与您要删除的行在同一范围内。 / p>

答案 1 :(得分:5)

如果它适合您的应用程序,那么您可以限制要删除的行数,并设置cronjob以重复删除。 E.g:

DELETE FROM tab WHERE .. LIMIT 1000

我发现在类似情况下这是一个很好的妥协。

答案 2 :(得分:0)

我使用删除程序

import React, { Component } from "react";
import { View, Text } from "react-native";
import RNFetchBlob from "rn-fetch-blob";

async function checkPaths(image_metadata_list) {

  const promises = image_metadata_list.map(async (image_metadata, idx) => {

    RNFetchBlob.fs.exists(image_metadata.device_path).then(exists => {
      if (exists === false) {
        console.log("image does not exist on device, downloading...");
        const dirs = RNFetchBlob.fs.dirs;
        const filename = (idx + 1).toString() + '.jpg'
        RNFetchBlob.config({
          path: dirs.DocumentDir + `/user_images/${filename}`
        }).fetch('GET', `${image_metadata.download_url}`).progress((received = 0, total = 0) => {
          //Handle progress of download here.. May be update UI...\
        }).then((resp) => {
          // update the device path
          image_metadata.device_path = resp.path();
          console.log("image path modified", image_metadata);
          return image_metadata;
        }).catch(e => {
          console.log("error downloading image", e);
        })
      }
      else {
        console.log("image path OK", image_metadata)
        return image_metadata;
      }
    })
  })
  console.log("promises", promises)
  results = await Promise.all(promises)
  return results;
}


export default class App extends Component {
  constructor(props) {
    super(props);
    this.image_references = [
       { device_path: 'badimagepath1', download_url:'mysecretdownloadurl1' },
       { device_path: 'badimagepath2', download_url: 'mysecretdownloadurl2' }
    ];
  }
  componentDidMount() {
    console.log("component mounted");
    console.log("checking image paths", JSON.stringify(this.image_references));
    checked_paths = checkPaths(this.image_references);
    console.log("checked image paths", JSON.stringify(checked_paths));
  }
  render() {
    return (
      <View style={{ flex: 1 }}>
        <Text>Welcome to MWE</Text>
      </View>
    )
  }
}

结束//