外部排序優化
優化外部排序
主要步驟重新拆分如下
第一階段
1.將未排序的大檔案切分(spilterReceiver)
2.一個執行緒池專門接收byte[],並將其轉化為long[] (prepareReceiver)
3.一個執行緒池專門排序long[] (sortReceiver)
4.一個執行緒池專門將已經有序的long[]寫入檔案 (writerReceiver)
這個過程直接寫long型別的數字到檔案,因為寫入文字佔用IO資源比直接寫入long型數字要多。
第二階段
1.一個執行緒用於歸併排序,將結果寫入緩衝區 (mergerReceiver)
2.如果緩衝區快滿了,就將其交給一個執行緒池用於寫入最終的檔案。 (mergerReceiver)
優化的重點是平衡CPU,記憶體和硬碟的資源使用。
每個電腦的配置不同,都需要進行不同的調整,才能達到最優化的效果。
單位的電腦是i5的CPU,8G記憶體,7200轉硬碟。
我使用的虛擬機器分配了2個核心,4G記憶體。
跑這個程式大致需要200s左右。
因為第二階段的第一個步驟是非常消耗CPU資源的,單位電腦CPU主頻很高,所以不會成為瓶頸。
而家裡的電腦,應該配置更接近吳老師做實驗的配置。主頻比較低,32位系統,4G記憶體。
這個配置明顯CPU成為瓶頸
在第一個階段,切分出來的檔案,由於CPU不能及時排序並輸出,經常導致OOM
只能在切分一個檔案出來之後,讓切分執行緒sleep一段時間,大量測試得到的結果是這個執行緒至少sleep2500毫秒才能不導致OOM。
也就是說,CPU運算的速度跟不上IO的速度。後來想到一個方法,加大分片。原來4G檔案使用15個分片,現在使用30個分片。資料快入快出,這樣可以避免OOM。至於這個分片的數字,恐怕每個機器都需要實際的測試。
另外在第二階段,也出現了CPU拖累IO,導致效能下降。
因為歸併的時候,需要大量運算各個分片中最小的資料,經常看到計算50M資料,CPU需要2s,而寫入一般1s就可以完成。
而這個過程是單執行緒的,CPU的主頻直接決定了外部排序的總體時間。
最近真的很忙,我這一個單執行緒的CPU居然都跑出了雙核的感覺。
我感覺優化就是找到慢的地方,看看是不是有無效的操作,如果都是有效運算,就只能想辦法使用多執行緒,使壓力分散在多個核心上。
之前吳老師說他用的是直接緩衝區+通道 IO的方式。自己寫程式將long直接轉化為byte。
這個優化的方式我試了一下,不能應用在我的場景。
他的本意是減少GC,但是在我的場景,這種方式更加劇了CPU的爭用。
優化的本質應該是平衡資源
程式日誌,相比最初的版本,效能提升了50s
因為將切分檔案,byte陣列轉為long陣列拆分為了兩個操作,並且使用了多執行緒處理。
主要步驟重新拆分如下
第一階段
1.將未排序的大檔案切分(spilterReceiver)
2.一個執行緒池專門接收byte[],並將其轉化為long[] (prepareReceiver)
3.一個執行緒池專門排序long[] (sortReceiver)
4.一個執行緒池專門將已經有序的long[]寫入檔案 (writerReceiver)
這個過程直接寫long型別的數字到檔案,因為寫入文字佔用IO資源比直接寫入long型數字要多。
第二階段
1.一個執行緒用於歸併排序,將結果寫入緩衝區 (mergerReceiver)
2.如果緩衝區快滿了,就將其交給一個執行緒池用於寫入最終的檔案。 (mergerReceiver)
優化的重點是平衡CPU,記憶體和硬碟的資源使用。
每個電腦的配置不同,都需要進行不同的調整,才能達到最優化的效果。
單位的電腦是i5的CPU,8G記憶體,7200轉硬碟。
我使用的虛擬機器分配了2個核心,4G記憶體。
跑這個程式大致需要200s左右。
因為第二階段的第一個步驟是非常消耗CPU資源的,單位電腦CPU主頻很高,所以不會成為瓶頸。
而家裡的電腦,應該配置更接近吳老師做實驗的配置。主頻比較低,32位系統,4G記憶體。
這個配置明顯CPU成為瓶頸
在第一個階段,切分出來的檔案,由於CPU不能及時排序並輸出,經常導致OOM
只能在切分一個檔案出來之後,讓切分執行緒sleep一段時間,大量測試得到的結果是這個執行緒至少sleep2500毫秒才能不導致OOM。
也就是說,CPU運算的速度跟不上IO的速度。後來想到一個方法,加大分片。原來4G檔案使用15個分片,現在使用30個分片。資料快入快出,這樣可以避免OOM。至於這個分片的數字,恐怕每個機器都需要實際的測試。
另外在第二階段,也出現了CPU拖累IO,導致效能下降。
因為歸併的時候,需要大量運算各個分片中最小的資料,經常看到計算50M資料,CPU需要2s,而寫入一般1s就可以完成。
而這個過程是單執行緒的,CPU的主頻直接決定了外部排序的總體時間。
-
import java.io.BufferedInputStream;
-
import java.io.File;
-
import java.io.FileInputStream;
-
import java.io.IOException;
-
import java.io.RandomAccessFile;
-
import java.nio.ByteBuffer;
-
import java.nio.MappedByteBuffer;
-
import java.nio.channels.FileChannel;
-
import java.nio.channels.FileChannel.MapMode;
-
import java.util.ArrayList;
-
import java.util.Arrays;
-
import java.util.Collections;
-
import java.util.List;
-
import java.util.concurrent.BrokenBarrierException;
-
import java.util.concurrent.CyclicBarrier;
-
import java.util.concurrent.ExecutorService;
-
import java.util.concurrent.Executors;
-
-
public class Controller {
-
public static void main(String[] args) throws IOException {
-
new Controller().action(new File("/home/lihuilin/桌面/t.txt"), 30, "/home/lihuilin/桌面/");
-
-
}
-
-
public void action(File file, int pieces, String outDir) throws IOException {
-
Invoker invoker = new Invoker(pieces);
-
List<Command> commandList = blocking(file, pieces, outDir);
-
for (Command command : commandList) {
-
command.setInvoker(invoker);
-
invoker.executeCommand(command);
-
}
-
}
-
-
private List<Command> blocking(File file, int pieces, String outDir) throws IOException {
-
List<Command> result = new ArrayList<Command>();
-
List<Long> list = new ArrayList<Long>();
-
list.add(-1L);
-
long length = file.length();
-
long step = length / pieces;
-
long index = 0;
-
for (int i = 0; i < pieces; i++) {
-
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
-
if (index + step < length) {
-
index = index + step;
-
in.skip(index);
-
while (in.read() != 10) {
-
index = index + 1;
-
}
-
list.add(index);
-
index++;
-
}
-
in.close();
-
}
-
list.add(length - 1);
-
for (int i = 0; i < list.size() - 1; i++) {
-
long skipSize = list.get(i) + 1;
-
long l = list.get(i + 1) - list.get(i);
-
result.add(new SpilterCommand(file, skipSize, l, outDir));
-
}
-
return result;
-
}
-
-
}
-
-
interface Command extends Comparable<Command> {
-
public void setInvoker(Invoker invoker);
-
-
public void setReceiver(Receiver receiver);
-
-
public void execute() throws IOException;
-
-
public long getSkipSize();
-
-
public int getLength();
-
-
public String getOutDir();
-
-
public File getSourceFile();
-
-
public Invoker getInvoker();
-
-
public void clear();
-
-
public File getOutFile();
-
-
public File getTargetFile();
-
}
-
-
class Invoker {
-
private Receiver sortReceiver;
-
private Receiver spilterReceiver;
-
private Receiver writerReceiver;
-
private Receiver prepareReceiver;
-
private Receiver mergerReceiver;
-
-
public Invoker(int pieces) {
-
writerReceiver = new WriterReceiver(pieces);
-
spilterReceiver = new SpilterReceiver();
-
sortReceiver = new SorterReceiver();
-
prepareReceiver = new PrepareReceiver();
-
mergerReceiver = new MergerReceiver();
-
}
-
-
public void executeCommand(Command command) {
-
try {
-
if (command instanceof SpilterCommand) {
-
spilterReceiver.action(command);
-
} else if (command instanceof PrepareCommand) {
-
prepareReceiver.action(command);
-
} else if (command instanceof SortCommand) {
-
sortReceiver.action(command);
-
} else if (command instanceof WriterCommand) {
-
writerReceiver.action(command);
-
} else if (command instanceof MergeCommand) {
-
mergerReceiver.action(command);
-
} else if (command instanceof KillCommand) {
-
writerReceiver.shutdown();
-
spilterReceiver.shutdown();
-
sortReceiver.shutdown();
-
prepareReceiver.shutdown();
-
mergerReceiver.shutdown();
-
}
-
} catch (IOException ex) {
-
ex.printStackTrace();
-
}
-
}
-
}
-
-
class SpilterCommand extends AbstractCommand {
-
-
public SpilterCommand(File sourceFile, long skipSize, long length, String outDir) {
-
super(sourceFile, skipSize, length, outDir);
-
}
-
-
@Override
-
public void clear() {
-
-
}
-
-
}
-
-
abstract class AbstractCommand implements Command {
-
private Invoker invoker = null;
-
private Receiver receiver = null;
-
private long skipSize = 0L;
-
private int length = 0;
-
private String outDir = null;
-
private File sourceFile;
-
private File outFile = null;
-
public static final long START = System.currentTimeMillis();
-
private static int FLAG = 0;
-
private File targetFile = null;
-
-
private synchronized int getFlag() {
-
return FLAG++;
-
}
-
-
public AbstractCommand(Command command) {
-
this(command.getSourceFile(), command.getSkipSize(), command.getLength(), command.getOutDir());
-
this.invoker = command.getInvoker();
-
if (command.getOutFile() != null) {
-
this.outFile = command.getOutFile();
-
} else {
-
this.outFile = new File(this.outDir + getFlag() + ".temp");
-
}
-
}
-
-
public AbstractCommand(File sourceFile, long skipSize, long length, String outDir) {
-
if (length > Integer.MAX_VALUE) {
-
throw new RuntimeException("長度溢位");
-
}
-
this.skipSize = skipSize;
-
this.length = (int) length;
-
this.outDir = outDir;
-
this.sourceFile = sourceFile;
-
this.targetFile = new File(outDir + "result.temp");
-
}
-
-
public void setInvoker(Invoker invoker) {
-
this.invoker = invoker;
-
}
-
-
public void setReceiver(Receiver receiver) {
-
this.receiver = receiver;
-
}
-
-
public long getSkipSize() {
-
return skipSize;
-
}
-
-
public int getLength() {
-
return length;
-
}
-
-
public String getOutDir() {
-
return outDir;
-
}
-
-
public File getSourceFile() {
-
return sourceFile;
-
}
-
-
@Override
-
public String toString() {
-
return "Command [skipSize=" + skipSize + ", length=" + length + "]";
-
}
-
-
public void execute() throws IOException {
-
this.receiver.action(this);
-
}
-
-
public Invoker getInvoker() {
-
return invoker;
-
}
-
-
public File getOutFile() {
-
return this.outFile;
-
}
-
-
public File getTargetFile() {
-
return this.targetFile;
-
}
-
-
@Override
-
public int compareTo(Command o) {
-
if (this.skipSize < o.getSkipSize()) {
-
return -1;
-
}
-
return 1;
-
}
-
}
-
-
interface Receiver {
-
public void action(Command command) throws IOException;
-
-
public void shutdown();
-
}
-
-
class PrepareReceiver implements Receiver {
-
private ExecutorService prepareThreadPool;
-
-
public PrepareReceiver() {
-
prepareThreadPool = Executors.newFixedThreadPool(4);
-
}
-
-
@Override
-
public void action(final Command command) throws IOException {
-
prepareThreadPool.submit(new Runnable() {
-
-
@Override
-
public void run() {
-
System.out.println("\t整理資料:" + command);
-
long start = System.currentTimeMillis();
-
-
byte[] data = ((PrepareCommand) command).getData();
-
long[] result = new long[getObjectSize(data)];
-
int resultIndex = 0;
-
int index = 0;
-
int first = 0;
-
while (index < data.length) {
-
if (data[index] == 10) {
-
byte[] tmpData = Arrays.copyOfRange(data, first, index);
-
String str = new String(tmpData);
-
result[resultIndex] = Long.valueOf(str);
-
resultIndex++;
-
first = index + 1;
-
}
-
-
index++;
-
}
-
command.getInvoker().executeCommand(new SortCommand(command, result));
-
-
result = null;
-
data = null;
-
command.clear();
-
-
long end = System.currentTimeMillis();
-
System.out.println("\t結束整理資料:" + command + ",用時:" + (end - start) / 1000);
-
}
-
-
});
-
-
}
-
-
private int getObjectSize(byte[] data) {
-
int size = 0;
-
for (byte b : data) {
-
if (b == 10) {
-
size++;
-
}
-
}
-
return size;
-
}
-
-
@Override
-
public void shutdown() {
-
this.prepareThreadPool.shutdown();
-
}
-
-
}
-
-
class PrepareCommand extends AbstractCommand {
-
-
private byte[] data;
-
-
public PrepareCommand(Command command, byte[] data) {
-
super(command);
-
this.data = data;
-
}
-
-
public byte[] getData() {
-
return this.data;
-
}
-
-
@Override
-
public void clear() {
-
this.data = null;
-
}
-
}
-
-
class SpilterReceiver implements Receiver {
-
@Override
-
public void action(final Command command) throws IOException {
-
try {
-
System.out.println("開始讀入:" + command);
-
long start = System.currentTimeMillis();
-
FileChannel in = new RandomAccessFile(command.getSourceFile(), "r").getChannel();
-
MappedByteBuffer inBuffer = in.map(MapMode.READ_ONLY, command.getSkipSize(), command.getLength());
-
byte[] data = new byte[inBuffer.limit()];
-
inBuffer.get(data);
-
command.getInvoker().executeCommand(new PrepareCommand(command, data));
-
-
data = null;
-
in.close();
-
command.clear();
-
-
long end = System.currentTimeMillis();
-
System.out.println("結束記憶體讀入:" + (end - start) / 1000 + "s");
-
-
} catch (IOException e) {
-
e.printStackTrace();
-
}
-
}
-
-
@Override
-
public void shutdown() {
-
}
-
}
-
-
class MergeCommand extends AbstractCommand {
-
private List<Command> commandList = null;
-
-
public MergeCommand(List<Command> commandList) {
-
super(commandList.get(0));
-
this.commandList = commandList;
-
}
-
-
@Override
-
public void clear() {
-
-
}
-
-
public List<Command> getCommandList() {
-
return this.commandList;
-
}
-
}
-
-
class KillCommand extends AbstractCommand {
-
-
public KillCommand(Command command) {
-
super(command);
-
}
-
-
@Override
-
public void clear() {
-
-
}
-
-
}
-
-
class MergerReceiver implements Receiver {
-
private ExecutorService mergerThreadPool = Executors.newFixedThreadPool(4);
-
private List<Worker> workerList = new ArrayList<Worker>();
-
private ByteBuffer bb = null;
-
-
@Override
-
public void action(final Command command) throws IOException {
-
bb = ByteBuffer.allocate(50 * 1024 * 1024);
-
List<Command> list = ((MergeCommand) command).getCommandList();
-
for (Command historyCommand : list) {
-
Worker worker = new Worker(historyCommand.getOutFile(), workerList);
-
workerList.add(worker);
-
}
-
-
System.out.println("讀取佇列,寫入目標檔案");
-
long start = System.currentTimeMillis();
-
RandomAccessFile targetFile = new RandomAccessFile(command.getTargetFile(), "rw");
-
FileChannel channel = targetFile.getChannel();
-
MappedByteBuffer out = null;
-
long index = 0L;
-
while (workerList.size() != 0) {
-
Worker worker = Collections.min(workerList);
-
Long data = worker.poll();
-
if (data == null) {
-
workerList.remove(worker);
-
} else {
-
-
bb.put((data + "\n").getBytes());
-
-
if (bb.position() > 49 * 1024 * 1024) {
-
long end = System.currentTimeMillis();
-
System.out.println("歸併用時:" + (end - start)/1000 + "s");
-
start = System.currentTimeMillis();
-
bb.flip();
-
long temp = bb.limit();
-
MutiWriter writer = new MutiWriter(channel, bb, index);
-
mergerThreadPool.submit(writer);
-
index = index + temp;
-
bb = ByteBuffer.allocate(50 * 1024 * 1024);
-
}
-
-
}
-
}
-
-
bb.flip();
-
-
out = channel.map(MapMode.READ_WRITE, index, bb.limit());
-
int i = bb.limit();
-
while (i > .0) {
-
out.put(bb.get());
-
i--;
-
}
-
out.force();
-
channel.close();
-
targetFile.close();
-
-
KillCommand killCommand = new KillCommand(command);
-
command.getInvoker().executeCommand(killCommand);
-
-
long end = System.currentTimeMillis();
-
System.out.println("外部排序總用時:" + (end - AbstractCommand.START) / 1000);
-
-
}
-
-
private class MutiWriter implements Runnable {
-
private ByteBuffer buffer;
-
private MappedByteBuffer out = null;
-
-
public MutiWriter(FileChannel channel, ByteBuffer buffer, long index) {
-
this.buffer = buffer;
-
try {
-
out = channel.map(MapMode.READ_WRITE, index, buffer.limit());
-
} catch (IOException e) {
-
e.printStackTrace();
-
}
-
}
-
-
@Override
-
public void run() {
-
long a1 = System.currentTimeMillis();
-
int i = buffer.limit();
-
while (i > 0) {
-
out.put(buffer.get());
-
i--;
-
}
-
out.force();
-
out = null;
-
long a2 = System.currentTimeMillis();
-
System.out.println("記憶體對映寫入:" + (a2 - a1) / 1000 + "s");
-
}
-
-
}
-
-
@Override
-
public void shutdown() {
-
mergerThreadPool.shutdown();
-
}
-
-
private class Worker implements Comparable<Worker> {
-
private long data;
-
private MappedByteBuffer buffer = null;
-
private List<Worker> workerList = null;
-
private boolean eof = false;
-
-
Worker(File file, List<Worker> workerList) {
-
try {
-
RandomAccessFile rFile = new RandomAccessFile(file, "r");
-
FileChannel channel = rFile.getChannel();
-
buffer = channel.map(MapMode.READ_ONLY, 0, channel.size());
-
-
this.workerList = workerList;
-
data = buffer.getLong();
-
-
rFile.close();
-
channel.close();
-
-
} catch (IOException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
}
-
-
public long peek() {
-
return data;
-
}
-
-
public Long poll() {
-
long result = data;
-
if (buffer.position() != buffer.limit()) {
-
data = buffer.getLong();
-
} else {
-
if (eof == false) {
-
eof = true;
-
} else {
-
return null;
-
}
-
}
-
-
return result;
-
}
-
-
@Override
-
public int compareTo(Worker o) {
-
if (this.peek() > o.peek()) {
-
return 1;
-
} else if (this.peek() < o.peek()) {
-
return -1;
-
} else {
-
return 0;
-
}
-
}
-
}
-
-
}
-
-
class WriterReceiver implements Receiver {
-
private ExecutorService writeThreadPool = null;;
-
private CyclicBarrier barrier = null;
-
private List<Command> commandList = new ArrayList<Command>();
-
-
public WriterReceiver(int pieces) {
-
writeThreadPool = Executors.newFixedThreadPool(pieces + 2);
-
barrier = new CyclicBarrier(pieces, new Runnable() {
-
-
@Override
-
public void run() {
-
long end = System.currentTimeMillis();
-
System.out.println("合併之前總用時:" + (end - AbstractCommand.START) / 1000);
-
-
MergeCommand command = new MergeCommand(WriterReceiver.this.commandList);
-
command.getInvoker().executeCommand(command);
-
-
}
-
});
-
-
}
-
-
@Override
-
public void action(final Command command) {
-
writeThreadPool.submit(new Runnable() {
-
-
@Override
-
public void run() {
-
long[] data = ((WriterCommand) command).getData();
-
-
try {
-
System.out.println("\t\t\t開始寫入:" + command);
-
long start = System.currentTimeMillis();
-
File outfile = command.getOutFile();
-
FileChannel channel = new RandomAccessFile(outfile, "rw").getChannel();
-
MappedByteBuffer buffer = channel.map(MapMode.READ_WRITE, 0, data.length * 8);
-
for (int i = 0; i < data.length; i++) {
-
buffer.putLong(data[i]);
-
}
-
buffer.force();
-
WriterReceiver.this.commandList.add(command);
-
long end = System.currentTimeMillis();
-
System.out.println("\t\t\t結束寫入:" + command + ",用時:" + (end - start) / 1000);
-
-
command.clear();
-
data = null;
-
channel.close();
-
buffer = null;
-
-
barrier.await();
-
} catch (IOException ex) {
-
ex.printStackTrace();
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
} catch (BrokenBarrierException e) {
-
e.printStackTrace();
-
}
-
}
-
});
-
}
-
-
@Override
-
public void shutdown() {
-
writeThreadPool.shutdown();
-
}
-
}
-
-
class SortCommand extends AbstractCommand {
-
private long[] data = null;
-
-
public SortCommand(Command command, long[] data) {
-
super(command);
-
this.data = data;
-
}
-
-
public long[] getData() {
-
return this.data;
-
}
-
-
@Override
-
public void clear() {
-
this.data = null;
-
}
-
-
}
-
-
class SorterReceiver implements Receiver {
-
private ExecutorService sortThreadPool = Executors.newFixedThreadPool(4);
-
-
public void action(final Command command) {
-
sortThreadPool.submit(new Runnable() {
-
-
@Override
-
public void run() {
-
System.out.println("\t\t開始排序:" + command);
-
long start = System.currentTimeMillis();
-
-
long[] data = ((SortCommand) command).getData();
-
Arrays.sort(data);
-
-
command.getInvoker().executeCommand(new WriterCommand(command, data));
-
-
data = null;
-
command.clear();
-
-
long end = System.currentTimeMillis();
-
System.out.println("\t\t結束排序:" + command + ",用時:" + (end - start) / 1000);
-
-
}
-
-
});
-
-
}
-
-
@Override
-
public void shutdown() {
-
sortThreadPool.shutdown();
-
}
-
}
-
-
class WriterCommand extends AbstractCommand {
-
private long[] data;
-
-
public WriterCommand(Command command, long[] data) {
-
super(command);
-
this.data = data;
-
}
-
-
public long[] getData() {
-
return this.data;
-
}
-
-
@Override
-
public void clear() {
-
this.data = null;
-
}
-
- }
我感覺優化就是找到慢的地方,看看是不是有無效的操作,如果都是有效運算,就只能想辦法使用多執行緒,使壓力分散在多個核心上。
之前吳老師說他用的是直接緩衝區+通道 IO的方式。自己寫程式將long直接轉化為byte。
這個優化的方式我試了一下,不能應用在我的場景。
他的本意是減少GC,但是在我的場景,這種方式更加劇了CPU的爭用。
優化的本質應該是平衡資源
程式日誌,相比最初的版本,效能提升了50s
因為將切分檔案,byte陣列轉為long陣列拆分為了兩個操作,並且使用了多執行緒處理。
- 開始讀入:Command [skipSize=0, length=135863265]
- 結束記憶體讀入:3s
- 整理資料:Command [skipSize=0, length=135863265]
- 開始讀入:Command [skipSize=135863265, length=135863254]
- 結束整理資料:Command [skipSize=0, length=135863265],用時:4
- 開始排序:Command [skipSize=0, length=135863265]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=271726519, length=135863267]
- 整理資料:Command [skipSize=135863265, length=135863254]
- 結束排序:Command [skipSize=0, length=135863265],用時:2
- 開始寫入:Command [skipSize=0, length=135863265]
- 結束記憶體讀入:3s
- 開始讀入:Command [skipSize=407589786, length=135863268]
- 整理資料:Command [skipSize=271726519, length=135863267]
- 結束寫入:Command [skipSize=0, length=135863265],用時:2
- 結束整理資料:Command [skipSize=135863265, length=135863254],用時:5
- 開始排序:Command [skipSize=135863265, length=135863254]
- 結束排序:Command [skipSize=135863265, length=135863254],用時:1
- 開始寫入:Command [skipSize=135863265, length=135863254]
- 結束整理資料:Command [skipSize=271726519, length=135863267],用時:4
- 開始排序:Command [skipSize=271726519, length=135863267]
- 結束排序:Command [skipSize=271726519, length=135863267],用時:1
- 開始寫入:Command [skipSize=271726519, length=135863267]
- 結束寫入:Command [skipSize=135863265, length=135863254],用時:6
- 結束寫入:Command [skipSize=271726519, length=135863267],用時:4
- 結束記憶體讀入:11s
- 整理資料:Command [skipSize=407589786, length=135863268]
- 開始讀入:Command [skipSize=543453054, length=135863264]
- 結束整理資料:Command [skipSize=407589786, length=135863268],用時:3
- 開始排序:Command [skipSize=407589786, length=135863268]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=679316318, length=135863268]
- 整理資料:Command [skipSize=543453054, length=135863264]
- 結束排序:Command [skipSize=407589786, length=135863268],用時:1
- 開始寫入:Command [skipSize=407589786, length=135863268]
- 結束寫入:Command [skipSize=407589786, length=135863268],用時:1
- 結束整理資料:Command [skipSize=543453054, length=135863264],用時:3
- 開始排序:Command [skipSize=543453054, length=135863264]
- 結束排序:Command [skipSize=543453054, length=135863264],用時:1
- 開始寫入:Command [skipSize=543453054, length=135863264]
- 結束寫入:Command [skipSize=543453054, length=135863264],用時:1
- 結束記憶體讀入:7s
- 整理資料:Command [skipSize=679316318, length=135863268]
- 開始讀入:Command [skipSize=815179586, length=135863264]
- 結束記憶體讀入:3s
- 開始讀入:Command [skipSize=951042850, length=135863270]
- 整理資料:Command [skipSize=815179586, length=135863264]
- 開始排序:Command [skipSize=679316318, length=135863268]
- 結束整理資料:Command [skipSize=679316318, length=135863268],用時:3
- 結束排序:Command [skipSize=679316318, length=135863268],用時:2
- 開始寫入:Command [skipSize=679316318, length=135863268]
- 結束整理資料:Command [skipSize=815179586, length=135863264],用時:4
- 開始排序:Command [skipSize=815179586, length=135863264]
- 結束寫入:Command [skipSize=679316318, length=135863268],用時:2
- 結束記憶體讀入:5s
- 整理資料:Command [skipSize=951042850, length=135863270]
- 開始讀入:Command [skipSize=1086906120, length=135863262]
- 結束排序:Command [skipSize=815179586, length=135863264],用時:1
- 開始寫入:Command [skipSize=815179586, length=135863264]
- 結束寫入:Command [skipSize=815179586, length=135863264],用時:1
- 整理資料:Command [skipSize=1086906120, length=135863262]
- 結束記憶體讀入:3s
- 開始讀入:Command [skipSize=1222769382, length=135863265]
- 開始排序:Command [skipSize=951042850, length=135863270]
- 結束整理資料:Command [skipSize=951042850, length=135863270],用時:4
- 結束記憶體讀入:3s
- 開始讀入:Command [skipSize=1358632647, length=135863256]
- 整理資料:Command [skipSize=1222769382, length=135863265]
- 結束排序:Command [skipSize=951042850, length=135863270],用時:2
- 開始寫入:Command [skipSize=951042850, length=135863270]
- 結束寫入:Command [skipSize=951042850, length=135863270],用時:1
- 結束整理資料:Command [skipSize=1086906120, length=135863262],用時:5
- 開始排序:Command [skipSize=1086906120, length=135863262]
- 結束排序:Command [skipSize=1086906120, length=135863262],用時:1
- 開始寫入:Command [skipSize=1086906120, length=135863262]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=1358632647, length=135863256]
- 開始讀入:Command [skipSize=1494495903, length=135863268]
- 結束寫入:Command [skipSize=1086906120, length=135863262],用時:1
- 開始排序:Command [skipSize=1222769382, length=135863265]
- 結束整理資料:Command [skipSize=1222769382, length=135863265],用時:6
- 結束排序:Command [skipSize=1222769382, length=135863265],用時:1
- 開始寫入:Command [skipSize=1222769382, length=135863265]
- 整理資料:Command [skipSize=1494495903, length=135863268]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=1630359171, length=135863255]
- 開始排序:Command [skipSize=1358632647, length=135863256]
- 結束整理資料:Command [skipSize=1358632647, length=135863256],用時:5
- 結束寫入:Command [skipSize=1222769382, length=135863265],用時:1
- 結束排序:Command [skipSize=1358632647, length=135863256],用時:1
- 開始寫入:Command [skipSize=1358632647, length=135863256]
- 結束整理資料:Command [skipSize=1494495903, length=135863268],用時:3
- 結束寫入:Command [skipSize=1358632647, length=135863256],用時:2
- 開始排序:Command [skipSize=1494495903, length=135863268]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=1630359171, length=135863255]
- 開始讀入:Command [skipSize=1766222426, length=135863271]
- 結束排序:Command [skipSize=1494495903, length=135863268],用時:1
- 開始寫入:Command [skipSize=1494495903, length=135863268]
- 結束寫入:Command [skipSize=1494495903, length=135863268],用時:1
- 結束整理資料:Command [skipSize=1630359171, length=135863255],用時:3
- 開始排序:Command [skipSize=1630359171, length=135863255]
- 整理資料:Command [skipSize=1766222426, length=135863271]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=1902085697, length=135863258]
- 結束排序:Command [skipSize=1630359171, length=135863255],用時:2
- 開始寫入:Command [skipSize=1630359171, length=135863255]
- 結束寫入:Command [skipSize=1630359171, length=135863255],用時:1
- 結束整理資料:Command [skipSize=1766222426, length=135863271],用時:3
- 開始排序:Command [skipSize=1766222426, length=135863271]
- 整理資料:Command [skipSize=1902085697, length=135863258]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=2037948955, length=135863254]
- 結束排序:Command [skipSize=1766222426, length=135863271],用時:1
- 開始寫入:Command [skipSize=1766222426, length=135863271]
- 結束寫入:Command [skipSize=1766222426, length=135863271],用時:1
- 結束整理資料:Command [skipSize=1902085697, length=135863258],用時:3
- 開始排序:Command [skipSize=1902085697, length=135863258]
- 整理資料:Command [skipSize=2037948955, length=135863254]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=2173812209, length=135863259]
- 結束排序:Command [skipSize=1902085697, length=135863258],用時:2
- 開始寫入:Command [skipSize=1902085697, length=135863258]
- 結束寫入:Command [skipSize=1902085697, length=135863258],用時:1
- 結束整理資料:Command [skipSize=2037948955, length=135863254],用時:3
- 開始排序:Command [skipSize=2037948955, length=135863254]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=2173812209, length=135863259]
- 開始讀入:Command [skipSize=2309675468, length=135863260]
- 結束排序:Command [skipSize=2037948955, length=135863254],用時:2
- 開始寫入:Command [skipSize=2037948955, length=135863254]
- 結束整理資料:Command [skipSize=2173812209, length=135863259],用時:3
- 開始排序:Command [skipSize=2173812209, length=135863259]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=2309675468, length=135863260]
- 開始讀入:Command [skipSize=2445538728, length=135863266]
- 結束寫入:Command [skipSize=2037948955, length=135863254],用時:2
- 結束排序:Command [skipSize=2173812209, length=135863259],用時:2
- 開始寫入:Command [skipSize=2173812209, length=135863259]
- 結束寫入:Command [skipSize=2173812209, length=135863259],用時:1
- 結束整理資料:Command [skipSize=2309675468, length=135863260],用時:3
- 開始排序:Command [skipSize=2309675468, length=135863260]
- 整理資料:Command [skipSize=2445538728, length=135863266]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=2581401994, length=135863268]
- 結束排序:Command [skipSize=2309675468, length=135863260],用時:2
- 開始寫入:Command [skipSize=2309675468, length=135863260]
- 結束寫入:Command [skipSize=2309675468, length=135863260],用時:1
- 結束整理資料:Command [skipSize=2445538728, length=135863266],用時:4
- 開始排序:Command [skipSize=2445538728, length=135863266]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=2581401994, length=135863268]
- 開始讀入:Command [skipSize=2717265262, length=135863264]
- 結束排序:Command [skipSize=2445538728, length=135863266],用時:2
- 開始寫入:Command [skipSize=2445538728, length=135863266]
- 結束寫入:Command [skipSize=2445538728, length=135863266],用時:1
- 結束整理資料:Command [skipSize=2581401994, length=135863268],用時:3
- 開始排序:Command [skipSize=2581401994, length=135863268]
- 整理資料:Command [skipSize=2717265262, length=135863264]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=2853128526, length=135863258]
- 結束排序:Command [skipSize=2581401994, length=135863268],用時:2
- 開始寫入:Command [skipSize=2581401994, length=135863268]
- 結束寫入:Command [skipSize=2581401994, length=135863268],用時:1
- 結束整理資料:Command [skipSize=2717265262, length=135863264],用時:3
- 開始排序:Command [skipSize=2717265262, length=135863264]
- 整理資料:Command [skipSize=2853128526, length=135863258]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=2988991784, length=135863254]
- 結束排序:Command [skipSize=2717265262, length=135863264],用時:2
- 開始寫入:Command [skipSize=2717265262, length=135863264]
- 結束寫入:Command [skipSize=2717265262, length=135863264],用時:1
- 結束整理資料:Command [skipSize=2853128526, length=135863258],用時:3
- 開始排序:Command [skipSize=2853128526, length=135863258]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=2988991784, length=135863254]
- 開始讀入:Command [skipSize=3124855038, length=135863260]
- 結束排序:Command [skipSize=2853128526, length=135863258],用時:2
- 開始寫入:Command [skipSize=2853128526, length=135863258]
- 結束寫入:Command [skipSize=2853128526, length=135863258],用時:1
- 結束整理資料:Command [skipSize=2988991784, length=135863254],用時:3
- 開始排序:Command [skipSize=2988991784, length=135863254]
- 整理資料:Command [skipSize=3124855038, length=135863260]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=3260718298, length=135863254]
- 結束排序:Command [skipSize=2988991784, length=135863254],用時:2
- 開始寫入:Command [skipSize=2988991784, length=135863254]
- 結束寫入:Command [skipSize=2988991784, length=135863254],用時:2
- 結束整理資料:Command [skipSize=3124855038, length=135863260],用時:4
- 開始排序:Command [skipSize=3124855038, length=135863260]
- 整理資料:Command [skipSize=3260718298, length=135863254]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=3396581552, length=135863262]
- 結束排序:Command [skipSize=3124855038, length=135863260],用時:1
- 開始寫入:Command [skipSize=3124855038, length=135863260]
- 結束寫入:Command [skipSize=3124855038, length=135863260],用時:2
- 結束整理資料:Command [skipSize=3260718298, length=135863254],用時:3
- 開始排序:Command [skipSize=3260718298, length=135863254]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=3396581552, length=135863262]
- 開始讀入:Command [skipSize=3532444814, length=135863265]
- 結束排序:Command [skipSize=3260718298, length=135863254],用時:1
- 開始寫入:Command [skipSize=3260718298, length=135863254]
- 結束寫入:Command [skipSize=3260718298, length=135863254],用時:2
- 結束整理資料:Command [skipSize=3396581552, length=135863262],用時:3
- 開始排序:Command [skipSize=3396581552, length=135863262]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=3532444814, length=135863265]
- 開始讀入:Command [skipSize=3668308079, length=135863273]
- 結束排序:Command [skipSize=3396581552, length=135863262],用時:2
- 開始寫入:Command [skipSize=3396581552, length=135863262]
- 結束寫入:Command [skipSize=3396581552, length=135863262],用時:2
- 結束整理資料:Command [skipSize=3532444814, length=135863265],用時:3
- 開始排序:Command [skipSize=3532444814, length=135863265]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=3668308079, length=135863273]
- 開始讀入:Command [skipSize=3804171352, length=135863261]
- 結束排序:Command [skipSize=3532444814, length=135863265],用時:2
- 開始寫入:Command [skipSize=3532444814, length=135863265]
- 結束寫入:Command [skipSize=3532444814, length=135863265],用時:1
- 結束整理資料:Command [skipSize=3668308079, length=135863273],用時:3
- 開始排序:Command [skipSize=3668308079, length=135863273]
- 整理資料:Command [skipSize=3804171352, length=135863261]
- 結束記憶體讀入:4s
- 開始讀入:Command [skipSize=3940034613, length=135862991]
- 結束排序:Command [skipSize=3668308079, length=135863273],用時:2
- 開始寫入:Command [skipSize=3668308079, length=135863273]
- 結束寫入:Command [skipSize=3668308079, length=135863273],用時:2
- 結束整理資料:Command [skipSize=3804171352, length=135863261],用時:3
- 開始排序:Command [skipSize=3804171352, length=135863261]
- 結束記憶體讀入:4s
- 整理資料:Command [skipSize=3940034613, length=135862991]
- 結束排序:Command [skipSize=3804171352, length=135863261],用時:1
- 開始寫入:Command [skipSize=3804171352, length=135863261]
- 結束寫入:Command [skipSize=3804171352, length=135863261],用時:1
- 結束整理資料:Command [skipSize=3940034613, length=135862991],用時:3
- 開始排序:Command [skipSize=3940034613, length=135862991]
- 結束排序:Command [skipSize=3940034613, length=135862991],用時:1
- 開始寫入:Command [skipSize=3940034613, length=135862991]
- 結束寫入:Command [skipSize=3940034613, length=135862991],用時:1
- 合併之前總用時:143
- 讀取佇列,寫入目標檔案
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 歸併用時:1s
- 記憶體對映寫入:3s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:5s
- 記憶體對映寫入:3s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:4s
- 記憶體對映寫入:2s
- 歸併用時:3s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 歸併用時:1s
- 歸併用時:2s
- 歸併用時:4s
- 記憶體對映寫入:6s
- 記憶體對映寫入:8s
- 記憶體對映寫入:4s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:3s
- 記憶體對映寫入:5s
- 記憶體對映寫入:2s
- 歸併用時:3s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:3s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:2s
- 歸併用時:2s
- 記憶體對映寫入:1s
- 外部排序總用時:351
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1172752/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 外部排序排序
- Orderby 排序優化排序優化
- 快速排序及其優化排序優化
- [Hive]Hive排序優化Hive排序優化
- 快速排序及優化排序優化
- oracle sql 排序優化OracleSQL排序優化
- 插入排序以及優化排序優化
- 如何優化氣泡排序?優化排序
- 氣泡排序及優化排序優化
- Mysql優化_ORDER BY和GROUP BY 的優化講解(單路排序和雙路排序)MySql優化排序
- SQL優化之利用索引排序SQL優化索引排序
- MySQL 5.7 ORDER BY排序的優化MySql排序優化
- 氣泡排序及優化詳解排序優化
- KunlunDB查詢優化(三)排序下推優化排序
- 大檔案排序優化實踐排序優化
- 三種快速排序演算法以及快速排序的優化排序演算法優化
- 選擇排序-演算法及優化排序演算法優化
- GBase8a資料排序優化排序優化
- MongoDB aggregate效能優化與排序MongoDB優化排序
- 分散式資料庫排序及優化分散式資料庫排序優化
- MySQL利用索引優化ORDER BY排序語句MySql索引優化排序
- 高效的SQL(index range scan優化排序)SQLIndex優化排序
- 八大排序演算法(2)_快速排序的優化排序演算法優化
- 9. 氣泡排序,以及如何優化氣泡排序,氣泡排序屬於插入排序排序優化
- MYSQL order by排序導致效率低小優化MySql排序優化
- group by排序,derived_merge優化的坑排序優化
- redis學習(六) 排序(sort,by,store,效能優化)Redis排序優化
- 三向切分的快速排序和優化排序優化
- SQL優化:組內排序取最大值SQL優化排序
- 外部排序中多路歸併排序,採用敗者樹比勝者樹更優的原因和簡易證明排序
- 基礎排序演算法詳解與優化排序演算法優化
- 資料結構:快速排序程式碼(已優化)資料結構排序優化
- 經典氣泡排序的分析、優化及測試排序優化
- SpringBoot外部化配置Spring Boot
- Java常見排序演算法之插入排序-簡單的效能優化技巧Java排序演算法優化
- 最簡單的氣泡排序還能怎麼優化?排序優化
- 資料結構java版之氣泡排序及優化資料結構Java排序優化
- 圖解氣泡排序及演算法優化(Java實現)圖解排序演算法優化Java